什么是std :: move的类型?

时间:2011-12-19 01:02:18

标签: c++ c++11 move-semantics

此代码按预期工作(在线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);

3 个答案:

答案 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);

将调用复制构造函数将vpv)复制到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);

只需vpv的r值引用即可。这不会导致调用移动构造函数或复制构造函数,也不会导致任何操作。

答案 2 :(得分:1)

auto vp = move(v);

正在创建一个新的vector<int>并调用它的移动构造函数:

vector(const vector<T>&& other);

会盗取v的内容。

因此'vp'的类型只是vector<int> ..没有涉及参考:

vector<int> vp;

它正在“移动”内部......而不是实际的矢量本身。

因此&vp&v不同..但内容会移动。