是否存在利用移动优势的back_inserter变体?

时间:2019-01-22 08:12:54

标签: c++11 iterator copy move push-back

在通用代码中,我试图告诉输出迭代器(实际上是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的东西吗?

3 个答案:

答案 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的一部分。

另请参阅: Why no emplacement iterators in C++11 or C++14?