是否有 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?