2011-12-19 144 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。這不會導致移動構造函數或拷貝構造函數被調用,也沒有任何東西被竊取。

相關問題