我在std :: vector上有一些奇怪的行为,添加了rvalues:
#include <iostream>
#include <vector>
class A {
public:
A():i_{5}{std::cout << "default" << std::endl;}
A(const A &data) { std::cout << "copied!" << std::endl; }
A(A &&data) { std::cout << "moved " << std::endl; }
int i_;
};
int main(int argc, char *argv[]) {
std::vector<A> datavec;
datavec.push_back(A{});
datavec.push_back(A{});
return 0;
}
输出是:
default
moved
default
moved
copied!
因此,矢量仍会创建A的副本,我所做的推动越多 - 我获得的副本就越多。 但是,如果我用默认值 A(A&amp;&amp; data)=默认值; 替换移动构造函数,或者用 A(const A&amp; data)= delete删除复制构造函数/ strong>我得到了正确的结果,没有制作副本。如果我先调用足够大小的datavec.reserve,我也没有副本。 我使用gcc版本5.4.0没有特定参数
g++ -std=c++11 -o main ../main.cpp
你有没有想过为什么矢量会复制明显的右值?我希望这不是STL的一些错误
答案 0 :(得分:13)
{em}内部缓冲区重新分配期间std::vector
正在复制元素。它选择复制而不是移动,因为您的移动构造函数未标记为noexcept
。标记它......
A(A &&) noexcept { std::cout << "moved " << std::endl; }
...将解决问题。
告诉编译器你的移动构造函数不会抛出允许std::vector
的实现在内部重新分配期间移动,实现C ++所要求的异常保证标准。
或者,您可以提前std::vector::reserve
您的容器,以防止内部缓冲区的增长。