Я говорю, что не доверяю никаким методам, вызываемым по ссылке на rvalue, чтобы не модифицировать объект, и я считаю, что делать это глупо. (Кроме того, ваш код ломается, если контейнер содержит ровно один элемент.)
йнеры C ++ 98 определили два типа итераторов,::iterator
с и::const_iterators
, Как правило, так:
struct vec{
iterator begin();
const_iterator begin() const;
};
В C ++ 11 эта часть дизайна кажется неизменной. Вопрос в том,для последовательности и для практических целей имеет смысл добавить::move_iterator
а также? или это излишество.
Я могу представить, что у контейнера rvalue могут быть перемещены их элементы, если это возможно.
class vec{
iterator begin() &;
const_iterator begin() const&;
move_iterator begin() &&;
};
Если я правильно понимаю, это может быть реализовано следующим образом:
auto vec::begin() &&{return std::make_move_iterator(this->begin());}
Конечно, обычный итератор может быть преобразован в итератор перемещения (сstd::make_move_iterator
), однако мотивация является общим кодом.
Например, с помощью итератора перемещения это будет очень элегантно реализовано без условий, зависящих от того, является ли аргумент lvalue или rvalue.
template<class Container, class T = Container::value_type>
void transport_first(Container&& c, std::vector<T>& v){
v.emplace_back(*std::forward<Container>(c).begin());
}
Обратите внимание, что этот код не будет иметь ненужных копий, если это возможно. Как это можно реализовать безmove_iterators
Сгенерированно с помощьюbegin
.
Я также понимаю, что этот вопрос касается практически любого средства доступа к контейнеру, например,operator[]
, front()
а такжеback()
.
template<class Value>
class vec{
using value_type = Value;
using reference = Value&;
using const_reference = Value const&;
using rvalue_reference = Value&&; // NEW!
reference front() &{...}
rvalue_reference front() &&{...} // NEW!
const_reference front() const&{...}
};
Возможно, контейнеры должны были быть переработаны с нуля в C ++ 11. Их дизайн показывает свой возраст.
Есть предложение автоматически выводить тип (decl)(*this)
в основном, все соответствующие перегрузки начала (и других функций-членов) бесплатно.