问题描述
考虑以下将一系列元素插入向量的程序:
Consider the following program which inserts a range of elements into a 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());
这有效地复制了范围,在目标向量中为整个范围分配了足够的空间,因此最多需要一次调整大小.现在考虑以下试图将范围移动到向量中的程序:
This efficiently copies the range, allocating enough space in the target vector for the entire range so that a maximum of one resize will be required. Now consider the following program which attempts to move a range into a 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");
for_each ( v2.begin(), v2.end(), [&v1]( string & s )
{
v1.emplace_back(std::move(s));
});
这执行了一个成功的移动,但没有享受到 insert() 在目标向量中预分配空间方面的好处,因此在操作期间可以多次调整向量的大小.
This performs a successful move but doesn't enjoy the benefits that insert() has with regard to preallocating space in the target vector, so the vector could be resized several times during the operation.
所以我的问题是,是否有一个插入等效项可以将范围移动到向量中?
So my question is, is there an insert equivalent which can move a range into a vector?
推荐答案
你使用 move_iterator
和 insert
:
v1.insert(v1.end(), make_move_iterator(v2.begin()), make_move_iterator(v2.end()));
24.5.3 中的例子几乎就是这样.
The example in 24.5.3 is almost exactly this.
如果 (a) vector::insert
使用迭代器标签调度来检测随机访问迭代器并预先计算大小(您假设它确实如此),您将获得所需的优化在您复制的示例中),并且(b) move_iterator
保留它包装的迭代器的迭代器类别(这是标准要求的).
You'll get the optimization you want if (a) vector::insert
uses iterator-tag dispatch to detect the random-access iterator and precalculate the size (which you've assumed it does in your example that copies), and (b) move_iterator
preserves the iterator category of the iterator it wraps (which is required by the standard).
在一个晦涩的地方:我很确定 vector::insert
可以从源中放置(这在这里无关紧要,因为源与目标的类型相同,所以 emplace与复制/移动相同,但与其他相同的示例相关).我还没有找到需要这样做的声明,我只是从迭代器对 i,j
的要求传递给 insert
是 T
是 EmplaceConstructible
from *i
.
On an obscure point: I'm pretty sure that vector::insert
can emplace from the source (which is irrelevant here, since the source is the same type as the destination, so an emplace is the same as a copy/move, but would be relevant to otherwise-identical examples). I haven't yet found a statement that it's required to do so, I've just inferred it from the fact that the requirement on the iterator pair i,j
passed to insert
is that T
be EmplaceConstructible
from *i
.
这篇关于是否有将范围移动到向量中的标准方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!