假设我有以下代码:
#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));
之间有什么区别?
答案 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(?)
(当你有简单的可复制对象时),因为移动构造函数需要归零\设置移动的对象,这实际上是你在写\复制两个对象