是否有移动范围为载体的标准方法?是否有移动范围为载体的标准方法?(Is there a standa

2019-05-14 11:05发布

考虑下面的程序,其插入一个范围的元素到载体的:

vector<string> v1;
vector<string> v2;

v1.push_back("one");
v1.push_back("two");
v1.push_back("three");

v2.push_back("four");
v2.push_back("five");
v2.push_back("six");

v1.insert(v1.end(), v2.begin(), v2.end());

这有效地复制的范围内,在用于使得将需要最多一个调整大小的整个范围内的目标矢量分配足够的空间。 现在考虑下面的程序,它试图移动范围为载体:

vector<string> v1;
vector<string> v2;

v1.push_back("one");
v1.push_back("two");
v1.push_back("three");

v2.push_back("four");
v2.push_back("five");
v2.push_back("six");

for_each ( v2.begin(), v2.end(), [&v1]( string & s )
{
    v1.emplace_back(std::move(s));
});

这将执行一个成功的举动,但不享受插入()有关于目标向量预分配空间的好处,所以矢量可以在操作过程中被调整几次。

所以我的问题是,是否有插入相当于可移动范围为载体?

Answer 1:

您可以使用move_iteratorinsert

v1.insert(v1.end(), make_move_iterator(v2.begin()), make_move_iterator(v2.end()));

在24.5.3的例子是几乎正是这一点。

你会得到你想要的优化,如果(一) vector::insert使用迭代器标签发送来检测随机访问迭代器和预先计算的大小(你认为它在你的例子,副本),和(b ) move_iterator保留它包装迭代器(这是由标准所要求的迭代器类别)。

在一个不起眼的一点:我敢肯定, vector::insert可以从源(这是这里无关紧要布设,因为源是同一类型作为目标,所以一个布设是一样的复制/移动,但将是相关的,否则,相同的实施例)。 我还没有找到一个声明,它的要求这样做,我只是推测它来自一个事实,即对迭代器对要求i,j传递给insert的是TEmplaceConstructible*i



Answer 2:

  1. std::move与预分配算法:

     #include <iterator> #include <algorithm> v1.reserve(v1.size() + v2.size()); // optional std::move(v2.begin(), v2.end(), std::back_inserter(v1)); 
  2. 下面将更加灵活且:

     v1.insert(v1.end(), std::make_move_iterator(v2.begin()), std::make_move_iterator(v2.end())); 

    史蒂夫·杰索普提供恰恰是它的背景信息以及它可能如何这样做。



文章来源: Is there a standard way of moving a range into a vector?