使用vector :: push_back移动

时间:2012-07-20 03:57:34

标签: c++ c++11

假设我有以下代码:

#include <vector>
struct A {
    int a;
    int x;
};
int main() {
    using namespace std;
    A a1;
    A a2;
    vector<A> va;
    va.push_back(a1);
    va.push_back(move(a2));
}

我知道std :: vector的元素是连续存储的,与std :: list不同。在上面的代码a2已被移动,但是真的没有将a2复制到向量va吗? va.push_back(a2);va.push_back(move(a2));之间有什么区别?

3 个答案:

答案 0 :(得分:37)

在您的情况下,没有有效的区别,因为您使用的是编译器提供的复制构造函数。当使用可移动构造的对象时,您会看到明显的性能差异,并且需要花费很多精力来复制。在这种情况下,使用push_back(x)会创建对象的副本,而push_back(move(x))会告诉push_back()它可以“窃取”x的内容,留下{{1}处于无法使用和未定义的状态。

考虑您是否有一个列表向量(x),并且您想要推送包含100,000个元素的列表。如果没有std::vector<std::list<int> >,将复制整个列表结构和所有100,000个元素。使用move()时,一些指针和其他一小部分数据会被混乱,这就是它。这将更快,并且将需要更少的总体内存消耗。

答案 1 :(得分:16)

当您使用va.push_back(a2)版本vector<T>::push_back(const T&)时,系统会调用va.push_back(move(a2)) vector<T>::push_back(T&&)版本{{1}}将被调用...

但在你的情况下,性能没有差别,因为

  

15非联合类的隐式定义的复制/移动构造函数   X执行其基础和成员的成员复制/移动。

第12.8段n3737草案。

答案 2 :(得分:0)

我想注意其他答案没有消失的事情;是?.push_back(move(?))在你的情况下会慢于?.push_back(?)(当你有简单的可复制对象时),因为移动构造函数需要归零\设置移动的对象,这实际上是你在写\复制两个对象