Ben*_*enj 52 c++ insert stdvector c++11
考虑以下程序,它将一系列元素插入到向量中:
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());
Run Code Online (Sandbox Code Playgroud)
这有效地复制了范围,在整个范围内为目标矢量分配了足够的空间,因此最多需要一个调整大小.现在考虑以下程序尝试将范围移动到向量中:
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));
});
Run Code Online (Sandbox Code Playgroud)
这会执行成功的移动,但不会享受insert()在目标向量中预分配空间方面的优势,因此在操作期间可以多次调整向量的大小.
所以我的问题是,是否有一个插入等效项可以将范围移动到向量中?
Ste*_*sop 81
您可以使用一个move_iterator具有insert:
v1.insert(v1.end(), make_move_iterator(v2.begin()), make_move_iterator(v2.end()));
Run Code Online (Sandbox Code Playgroud)
24.5.3中的例子几乎就是这个.
如果(a)vector::insert使用iterator-tag dispatch来检测随机访问迭代器并预先计算大小(你假设它在你的示例中复制了),并且(b)move_iterator保留迭代器,你将得到你想要的优化它包装的迭代器的类别(标准所要求的).
在一个不起眼的地方:我很确定它vector::insert可以从源头放置(这里不相关,因为源是与目的地相同的类型,因此一个空格与复制/移动相同,但是与之相关否则相同的例子).我还没有找到一个声明,它的要求这样做,我只是一个事实,即对迭代器对的要求推断它i,j传递到insert的是,T是EmplaceConstructible从*i.
seh*_*ehe 33
std::move 预分配算法:
#include <iterator>
#include <algorithm>
v1.reserve(v1.size() + v2.size()); // optional
std::move(v2.begin(), v2.end(), std::back_inserter(v1));
Run Code Online (Sandbox Code Playgroud)以下将更灵活:
v1.insert(v1.end(),
std::make_move_iterator(v2.begin()),
std::make_move_iterator(v2.end()));
Run Code Online (Sandbox Code Playgroud)
Steve Jessop提供了有关它的确切内容的背景信息,以及它是如何做到的.