我试图理解以下行为:
#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
s 复制赋值运算符,其中std::vector::insert
used.
为什么std::vector::insert
需要复制分配std::vector::push_back
复制构造?这是否意味着手动连接两个向量可以更有效?这是使用 LLVM。
从逻辑上讲,没有理由需要赋值运算符。这insert
完全可以通过移动任何现有元素来实现操作vec[x]
to vec[x+1]
通过(大致)使用vec[x+1].~T(); new(&vec[x+1]) T(std::move(vec[x]));
在循环中销毁现有元素,并使用就地构造将前一个元素向前移动。
然而,一种更自然的编写方法是使用赋值来实现这一点,在设计良好的类中,即使不是更高效,至少也同样有效:vec[x+1] = std::move(vec[x]);
。一个简单的例子说明何时可以更有效,如果向量元素的构造和销毁涉及分配和释放内存:使用赋值可以轻松绕过这一点。
我们决定允许向量使用赋值运算符利大于弊。你们的班级很不寻常,而你们的班级恰好没有从这个决定中受益。不幸的是,但没有办法设计出适合每个用例的向量。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)