此代码按预期工作(在线here)。
最后v
为空,w
不为空,因为它已经窃取了v
的内容。
vector<int> v;
v.push_back(1);
cout << "v.size(): " << v.size() << endl;
auto vp = move(v);
vector<int> w(vp);
cout << "w.size(): " << w.size() << endl;
cout << "v.size(): " << v.size() << endl;
但如果我用
替换auto vp=move(v)
vector<int> && vp = move (v);
然后它不动了。相反,它复制,两个向量最后都是非空的。如图所示here。
澄清:更具体地说,vp
的自动派生类型是什么?如果它不是vector<int> &&
,那还有什么呢?为什么这两个例子虽然如此相似,却给出了不同的结果?
额外:我也试过了,它仍然复制而不是移动
std :: remove_reference< vector<int> > :: type && vp = move(v);
答案 0 :(得分:12)
编辑OP的澄清:auto
派生的move(v)
类型为vector<int>
。请参阅C++11 "auto" semantics。
第一个例子是这样做的:
move 'v' into 'vp'
copy 'vp' into 'w'
,第二个例子做到了这一点:
set 'vp' as rvalue-reference of 'v'
copy 'vp' (which is 'v') into 'w'
std:move
所做的只是将一个类型转换为右值(参见What is std::move(), and when should it be used?)。因此,在
vector<int>&& vp = move(v);
它只是将rvalue-reference vp
设置为v
而不执行任何其他操作。另外,rvalue-reference是一个左值(它有一个名字),所以
vector<int> w(vp);
将调用复制构造函数将vp
(v
)复制到w
。
如果你将vp
作为右值(Example),它会调用移动构造函数:
vector<int> w(move(vp))
您可能需要阅读此内容:C++ Rvalue References Explained。
答案 1 :(得分:2)
在第一种情况下:
auto vp = move(v);
相当于:
vector<int> vp = move(v);
这会调用移动构造函数,因为move(v)
的类型为vector<int>&&
,因此vp
最终会窃取v
的内容。
在第二种情况下:
vector<int>&& vp = move(v);
只需vp
对v
的r值引用即可。这不会导致调用移动构造函数或复制构造函数,也不会导致任何操作。
答案 2 :(得分:1)
auto vp = move(v);
正在创建一个新的vector<int>
并调用它的移动构造函数:
vector(const vector<T>&& other);
会盗取v
的内容。
因此'vp'的类型只是vector<int>
..没有涉及参考:
vector<int> vp;
它正在“移动”内部......而不是实际的矢量本身。
因此&vp
与&v
不同..但内容会移动。