有一个标准的方法将范围移动到vector中吗?
考虑下面的程序,它将一系列元素插入到一个向量中:
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()在预先分配目标向量中的空间方面的好处,所以在操作过程中可以重新调整向量的大小。
所以我的问题是,有一个插入等价物可以将范围移动到一个向量?
你使用insert
的move_iterator
:
v1.insert(v1.end(), make_move_iterator(v2.begin()), make_move_iterator(v2.end()));
24.5.3中的例子几乎就是这样。
(a) vector::insert
使用iterator-tag dispatch检测随机访问迭代器并预先计算大小(假设它在你的例子中复制),并且(b) ) move_iterator
保留了它所包装的迭代器的迭代器类别(这是标准所要求的)。
在一个晦涩的地方:我敢肯定, vector::insert
可以从源代码(这是无关的,因为源是目的地相同的types,所以一个地方是一样的复制/移动,但将与其他相同的例子相关)。 我还没有find一个需要这样做的声明,我只是从这样一个事实推断出来的,即对i,j
传入的迭代器对的要求是从*i
是EmplaceConstructible
。
-
带预分配的
std::move
algorithm:#include <iterator> #include <algorithm> v1.reserve(v1.size() + v2.size()); // optional std::move(v2.begin(), v2.end(), std::back_inserter(v1));
-
以下将更加灵活:
v1.insert(v1.end(), std::make_move_iterator(v2.begin()), std::make_move_iterator(v2.end()));
史蒂夫·杰索普(Steve Jessop)提供了关于它究竟是什么的背景信息,可能是如何做的