2011-12-19 80 views
4

此代码按预期工作(在线here)。 最后v为空,w不为空,因为它已经窃取了v的内容。什么是std :: move的类型?

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; 

但是,如果我有

vector<int> && vp = move (v); 

更换auto vp=move(v)然后,它不动。相反,它的副本和两个矢量在最后都是非空的。如here所示。

澄清:更具体地说,什么是自动派生类型vp?如果它不是vector<int> &&,那还有什么呢?为什么这两个例子虽然如此相似,却给出了不同的结果?

额外:我也试过这样,它仍然被复制而不是移动

std :: remove_reference< vector<int> > :: type && vp = move(v); 
+0

['move' returns'std :: remove_reference :: type &&'](http://en.cppreference.com/w/cpp/utility/move) – 2011-12-19 01:07:15

+1

事实上,'vector_reference'上的'vector '就我所知,只是给了我们'矢量'。 – 2011-12-19 01:11:09

+0

我试过'std :: remove_reference < vector> :: type && vp = move(v);'但它也不起作用。它复制,不移动。 – 2011-12-19 01:13:27

回答

12

编辑为OP的澄清:在auto衍生型move(v)vector<int>。请参阅C++11 "auto" semantics

第1例做到这一点:

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

它只是右值引用vp设置为v和别的什么也不做。此外,右值引用是一个左值(它有一个名字),所以

vector<int> w(vp); 

将调用拷贝构造函数来复制vp(这是v)为w

它会调用移动构造函数,如果你让vp右值(Example):

vector<int> w(move(vp)) 

您可能需要阅读此:C++ Rvalue References Explained

+0

这并不能解释为什么一种方法有效,但另一种方法不能。 – 2011-12-19 01:06:42

+2

但它没有在第一个例子中调用复制构造函数。 'auto vp = move(v);向量 w(vp)'工作(数据被窃取)。为什么这个工作?什么是vp的自动派生类型? – 2011-12-19 01:07:18

+0

@AaronMcDaid:* *调用复制构造函数,不调用'v'。查看更新。 – kennytm 2011-12-19 01:13:43

1
auto vp = move(v); 

是创建一个新vector<int>并调用它的移动的构造:

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

这将窃取的v内容。

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

vector<int> vp; 

这是'移动'的内部..不是实际的向量本身。

因此&vp将与&v不同,但内容会移动。

2

在第一种情况:

auto vp = move(v); 

相当于:

vector<int> vp = move(v); 

这将调用移动构造,由于move(v)具有类型vector<int>&&,因此vp结束偷窃的v内容。

在第二种情况:

vector<int>&& vp = move(v); 

只是使vp的r值参照v。这不会导致移动构造函数或拷贝构造函数被调用,也没有任何东西被窃取。

相关问题