是否有 back_inserter 变体利用移动?
Is there a back_inserter variant that takes advantage of move?
在通用代码中,我试图告诉输出迭代器(实际上是 std::back_inserter_iterator
移动一系列元素。令我惊讶的是,它看起来好像元素是在 move-to-back_inserter 操作中移动的.
#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
在动吗?
是否已经有利用 move/emplace 的 std::back_inserter
变体? 类似 std::back_emplacer
的东西?
std::back_inserter()
is a convenience function template for creating an std::back_insert_iterator
对象。
class std::back_insert_iterator
已经 operator=
超载以获取 右值引用 类型,即:
back_insert_iterator<Container>& operator=(typename Container::value_type&& value);
因此,std::back_insert_iterator
已经准备好利用移动语义。
如果 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) Results in container->push_back(value)
2) Results in container->push_back(std::move(value))
回到你原来的问题
Is there a std::back_inserter really moving somehow?
是的,此函数创建的迭代器确实利用了右值引用参数。
Is there already a variant of std::back_inserter that takes advantage of move/emplace?
没有,但是可以实现。参见 this answer。
Is there already a variant of std::back_inserter that takes advantage
of move/emplace? Something like an std::back_emplacer?
此处描述了back_emplacer:
但它不是标准的一部分。
另请参阅:
Why no emplacement iterators in C++11 or C++14?
在通用代码中,我试图告诉输出迭代器(实际上是 std::back_inserter_iterator
移动一系列元素。令我惊讶的是,它看起来好像元素是在 move-to-back_inserter 操作中移动的.
#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
在动吗?
是否已经有利用 move/emplace 的 std::back_inserter
变体? 类似 std::back_emplacer
的东西?
std::back_inserter()
is a convenience function template for creating an std::back_insert_iterator
对象。
class std::back_insert_iterator
已经 operator=
超载以获取 右值引用 类型,即:
back_insert_iterator<Container>& operator=(typename Container::value_type&& value);
因此,std::back_insert_iterator
已经准备好利用移动语义。
如果 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) Results in container->push_back(value)
2) Results in container->push_back(std::move(value))
回到你原来的问题
Is there a std::back_inserter really moving somehow?
是的,此函数创建的迭代器确实利用了右值引用参数。
Is there already a variant of std::back_inserter that takes advantage of move/emplace?
没有,但是可以实现。参见 this answer。
Is there already a variant of std::back_inserter that takes advantage of move/emplace? Something like an std::back_emplacer?
此处描述了back_emplacer:
但它不是标准的一部分。
另请参阅: Why no emplacement iterators in C++11 or C++14?