С++ 11向量使得上右值
问题描述:
副本我有性病:: vector的一些奇怪的行为与添加右值:С++ 11向量使得上右值
#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 & & data)= default;或删除拷贝构造函数与A(const A & data)= delete;我得到正确的结果,没有副本。如果我第一次调用足够大小的datavec.reserve,我也没有副本。 我用gcc版本5.4.0,没有具体的参数
g++ -std=c++11 -o main ../main.cpp
你有为什么矢量使得明显右值的副本有什么想法?我希望它不是STL的某个bug
答
std::vector
在内部缓冲区重新分配期间正在复制你的元素。它选择复制而不是移动,因为您的移动构造函数未标记为noexcept
。标记它...
A(A &&) noexcept { std::cout << "moved " << std::endl; }
...将解决问题。
告诉编译器,你转移构造不会抛出允许std::vector
的实现内部重新分配过程中移动,实现由C++标准要求的例外保证。
或者,您可以预先将您的容器std::vector::reserve
以防止内部缓冲区的增长。
伟大的问题,很好的答案,和伟大的重复点。 – Bathsheba