С++ 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

+1

伟大的问题,很好的答案,和伟大的重复点。 – Bathsheba

std::vector内部缓冲区重新分配期间正在复制你的元素。它选择复制而不是移动,因为您的移动构造函数未标记为noexcept。标记它...

A(A &&) noexcept {  std::cout << "moved " << std::endl; } 

...将解决问题。

告诉编译器,你转移构造不会抛出允许std::vector的实现内部重新分配过程中移动,实现由C++标准要求的例外保证

或者,您可以预先将您的容器std::vector::reserve以防止内部缓冲区的增长。