【发布时间】:2018-08-01 14:58:43
【问题描述】:
C++98 容器定义了两种迭代器,::iterators 和::const_iterators。一般是这样的:
struct vec{
iterator begin() ;
const_iterator begin() const;
};
在 C++11 中,这部分设计似乎没有改变。
问题是,
为了一致性和实用目的,是否也添加 ::move_iterators 有意义? 还是有点矫枉过正。
我可以想象,如果可能,右值容器可能会移动其元素。
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),但其动机是通用代码。
例如,使用移动迭代器,这将非常优雅地实现,没有条件取决于参数是左值还是右值。
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());
}
请注意,如果可能,此代码不会产生不必要的副本。
如果没有begin生成的move_iterators,这怎么实现。
我也意识到这个问题几乎适用于容器的所有访问者,例如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 中从头开始重新设计。 他们的设计正在显示它的时代。
有一个提议,自动推导出(*this)的(decl)类型,基本上所有相应的begin(和其他成员函数)的重载都是免费的。
【问题讨论】:
标签: c++11 stl iterator move const-iterator