在通用代码中,我试图告诉输出迭代器(实际上是std::back_inserter_iterator
来移动一系列元素。令我惊讶的是,看起来好像元素是在move-to-back_inserter操作中移动的。 / p>
#include<algorithm> // move
#include<iterator> // back_inserter
#include<vector>
int main(){
std::vector<std::vector<double> > v(10, std::vector<double>(100));
std::vector<std::vector<double> > w;
assert( not v[0].empty() and w.size() == 0 );
std::copy(v.begin(), v.end(), std::back_inserter(w));
assert( not v[0].empty() and w.size() == 10 );
std::move(v.begin(), v.end(), std::back_inserter(w));
assert( v[0].empty() and w.size() == 20 ); // were v elements moved to w?
}
但是,我认为v
的元素实际上没有移到w
的可能性,因为毕竟back_inserter
会做一个push_back
,这意味着一个副本到w
。
在std::move
情况下,似乎v
元素被移到了临时元素之后才被复制到w
中。
对吗?有std::back_inserter
确实以某种方式移动吗?
是否已经有std::back_inserter
的变体可以利用移动/进位?类似std::back_emplacer
的东西吗?
答案 0 :(得分:1)
std::back_inserter()
是用于创建std::back_insert_iterator
对象的便捷功能模板。
std::back_insert_iterator
类已经operator=
重载,用于获取 rvalue引用类型,即:
back_insert_iterator<Container>& operator=(typename Container::value_type&& value);
因此,std::back_insert_iterator
已经准备好利用移动语义。
答案 1 :(得分:1)
如果std::back_insert_iterator
除了在构造容器上调用push_back
之外什么也不做,则可以通过查看std::vector::push_back
重载集来回答问题:
void push_back(const T& value);
void push_back(T&& value);
因此,在这里,我们显然有右值引用的重载。如果相应的std::back_insert_iterator
在用右值引用调用时复制其参数,那会不会很奇怪?确实,我们再次有一个非常相似的overload set:
back_insert_iterator<Container>&
operator=(typename Container::const_reference value);
back_insert_iterator<Container>&
operator=(const typename Container::value_type& value);
带有其他注释
1)结果在容器中-> push_back(value)
2)结果在container-> push_back(std :: move(value))
回到您的原始问题
std :: back_inserter是否真的以某种方式移动?
是的,此函数创建的迭代器确实利用了右值引用参数。
是否已经存在利用move / emplace优势的std :: back_inserter变体?
否,但是可以实现。参见this answer。
答案 2 :(得分:1)
是否已有利用std :: back_inserter的变体 /位置?像std :: back_emplacer一样的东西?
这里描述了back_emplacer: https://stackoverflow.com/a/12131700/7471760
但这不是std的一部分。