问题描述
我想了解以下行为:
#include <vector>
#include <iterator>
struct Foo {
Foo(int a) : a_ {a} {}
const int a_; // Note the const
};
int main(int argc, char **argv) {
std::vector<Foo> v1 {Foo {0}};
std::vector<Foo> v2 {Foo {1}};
auto first = std::begin(v2);
auto last = std::end(v2);
for (; first != last; ++first) {
v1.push_back(*first); // Fine
}
//v1.insert(v1.begin(), first, last); // Does not compile
return 0;
}
原来 const
Foo
的成员隐含地删除了 Foo
的副本赋值运算符, std: :vector :: insert
使用。
It turns out the const
member of Foo
was implicitly deleting Foo
s copy-assignment operator, which std::vector::insert
used.
为什么 std :: vector :: insert
需要复制assign std :: vector :: push_back
复制构造?这是否意味着可以更有效地手动连接两个向量?这是使用LLVM。
Why does std::vector::insert
need to copy assign while std::vector::push_back
copy constructs? Does this mean it can be more efficient to manually concatenate two vectors? This is using LLVM.
推荐答案
逻辑上没有理由要求赋值运算符。 insert
操作可以完全通过将任何现有元素 vec [x]
移动到 vec (大致)
在一个循环中销毁一个现有的元素, vec [x + 1]。〜T(); [x + 1]
新的(& vec [x + 1])T(std :: move(vec [x]));
There is no reason why an assignment operator would be required, logically speaking. The insert
operation can be implemented entirely by moving any existing element vec[x]
to vec[x+1]
by using (roughly) vec[x+1].~T(); new(&vec[x+1]) T(std::move(vec[x]));
in a loop to destroy an existing element, and use in-place construction to move the previous element forward.
然而,一个更自然的方法来编写这个,在设计良好的类中通常至少是同样有效的,如果不是更多,也是使用赋值为: vec [x + 1] = std :: move(vec [x]);
。一个简单的例子,当它可以更有效率是如果矢量的元素的构造和销毁涉及分配和释放内存:使用赋值容易绕过这一点。
However, a more natural approach to write this, which in well-designed classes is typically at least as efficient if not more so too, is to use assignment for that: vec[x+1] = std::move(vec[x]);
. An easy example of when it can be more efficient is if the construction and destruction of the vector's elements involves allocating and deallocating memory: using assignment easily bypasses that.
使得允许向量使用赋值运算符比缺点有更多的好处。你的班级是不寻常的,你的班级不会从这个决定中受益。这是不幸的,但没有办法设计一个完美的每个用例的向量。
A decision was made that allowing vectors to use assignment operators has more benefits than drawbacks. Your class is unusual, and your class happens not to benefit from this decision. It's unfortunate, but there's no way of designing a vector that's perfect for every use case.
这篇关于为什么std :: vector :: insert需要复制assign?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!