Для начала, короткий фрагмент того, чего я хочу достичь:
std::vector<std::string> v{ "one", "two", "three", "four" };
for (const std::string& str : drop_last(v)) {
cout << str << ' ';
}
Приведенный выше код должен напечатать: «один два три».
Чтобы сделать это возможным,Я реализовал следующую структуру:
template <typename Container>
struct drop_last {
using const_iterator = typename Container::const_iterator;
explicit drop_last(const Container& container_) : m_container(container_) {}
const_iterator begin() {
return m_container.begin();
}
const_iterator end() {
return m_container.empty() ? m_container.end() : std::prev(m_container.end());
}
private:
const Container& m_container;
};
Этот код работает нормально, кроме случаев, когда он работает с временными объектами (в этом случае assert "не может разыменовать инициализированное значением значение итератор карты / набора"):
std::vector<int> return_temporary_vector() {
vector<int> v;
// ...
return v;
}
int main(int argc_, char* argv_[]) {
for (int value : drop_last(return_temporary_vector())) {
// ...
}
// ...
}
Как мне адаптировать структуру drop_last
так, чтобы выполнялись следующие условия:
- правильная работа с временными объектами
- по возможности избегать ненужного копирования. То есть простая замена
const Container& m_container;
на Container m_container;
не подходит.