54

假设我有以下代码:

#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));

4

3 回答 3

58

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

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

于 2012-07-20T04:03:11.263 回答
22

当你使用va.push_back(a2)版本vector<T>::push_back(const T&)时会被调用,当你使用va.push_back(move(a2))版本时vector<T>::push_back(T&&)会被调用......

但是在您的情况下,性能没有区别,因为

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

第 12.8 段 n3337 草案。

于 2012-07-20T03:59:36.927 回答
0

我想指出其他答案没有提到的东西;是这?.push_back(move(?))将比?.push_back(?)你的情况慢(当你有微不足道的可复制对象时),因为移动构造函数需要归零\设置移动的对象,这实际上是你正在编写\复制两个对象。

于 2016-11-19T17:10:01.897 回答