是否有将范围移动到矢量中的标准方法



考虑以下程序,它将一系列元素插入到向量中:

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));
});

这将执行成功的移动,但不能享受 insert() 在目标向量中预分配空间的好处,因此在操作过程中可以多次调整向量的大小。

所以我的问题是,是否有可以将范围移动到向量中的插入等效项?

您使用带有insertmove_iterator

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

24.5.3 中的示例几乎正是这个。

如果 (a) vector::insert使用迭代器标记调度来检测随机访问迭代器并预先计算大小(您在复制的示例中假设它确实如此),并且 (b) move_iterator保留它包装的迭代器的迭代器类别(这是标准所要求的)。

在一个晦涩的点上:我很确定vector::insert可以从源进行放置(这在这里无关紧要,因为源与目标的类型相同,因此放置与复制/移动相同,但与其他相同的示例相关)。我还没有找到需要这样做的声明,我只是从迭代器对的要求i,j传递给insert的事实中推断出T*i EmplaceConstructible

  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()));
    

    史蒂夫·杰索普(Steve Jessop)提供了有关其确切功能以及可能如何这样做的背景信息。

最新更新