Mover iteradores para contêineres?
Os contêineres C ++ 98 definiram dois tipos de iterador,::iterator
areia::const_iterators
. Geralmente, assim:
struct vec{
iterator begin();
const_iterator begin() const;
};
No C ++ 11, essa parte do design parece inalterada. A questão é,por coerência e por motivos práticos, faria sentido adicionar::move_iterator
s também? ou é um exagero.
Eu posso imaginar que um contêiner rvalue talvez tenha seus elementos movidos, se possível.
class vec{
iterator begin() &;
const_iterator begin() const&;
move_iterator begin() &&;
};
Se bem entendi, poderia ser implementado assim em casos simples:
auto vec::begin() &&{return std::make_move_iterator(this->begin());}
Obviamente, um iterador normal pode ser convertido em um iterador de movimento (comstd::make_move_iterator
), no entanto, as motivações são códigos genéricos.
Por exemplo, com um iterador de movimentação, isso seria muito elegantemente implementado sem condições, dependendo se o argumento é um lvalue ou um 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());
}
Observe que esse código não gera cópias desnecessárias, se possível. Como isso pode ser implementado semmove_iterators
gerado porbegin
.
Também sei que essa pergunta se aplica a quase qualquer acessador do contêiner, por exemplo,operator[]
, front()
eback()
.
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&{...}
};
Talvez os contêineres devam ter sido reprojetados do zero no C ++ 11. Seu design está mostrando sua idade.
Existe uma proposta para deduzir automaticamente o tipo (declínio) de(*this)
basicamente tendo toda a sobrecarga correspondente de begin (e outras funções membro) gratuitamente.