2014-04-11 201 views

回答

3

這兩個代碼都是正確的,在C++中是100%合法的。只有在第一種情況下引用被移動(或者更好地說,在使用適當的目的地時能夠移動)並且在第二種情況下,它是副本(參見下面的示例以便解釋這個)

請注意,std::move實際上並沒有移動對象。它僅將該對象轉換爲右值引用類型。就是這樣。

還要注意,在這兩種案件,rvalueRef仍然左值—一個對象,它有一個名字(即一個標識符來指代)是從來沒有一個rvalue。所以,如果你實際上沒有使用std::move(或使用顯式投射)實際移動它,那麼根本沒有任何區別。

這裏是一個具體的例子:

​​

您的代碼如下:

std::string& ref = GetReference(); 
std::string&& rvalueRef = std::move(ref); 

std::string value = GetValue() 
std::string&& rvalueCopy = std::move(value); //named changed 

至今並無影響。

但是,如果你這樣做:

f(std::move(rvalueRef)); //actual object returned from GetReference is moved! 
f(std::move(rvalueCopy)); //only a copy is moved. 

實際對象移動在第一種情況下,和在第二種情況下,複製移動。

f(std::move(GetReference())); //actual object returned from GetReference is moved! 
f(std::move(GetValue()));  //only a copy is moved. 

所以你看,在你的代碼,沒有任何區別,因爲在所有沒有實際MOVE:如果這樣做,這是沒有任何差別。只有演員在那裏。爲了實際移動,應該有一個適當的目標類型,可以調用移動構造函數或移動賦值!在你的情況下,沒有任何一個的調用。

1

問:有一個右值引用右值引用是合法嗎?

這不是你問的問題。您真正要問的問題是這樣的:

問:將左值引用轉換爲右值引用是合法嗎?

答案是肯定的。 std::move只是將它的參數轉換爲一個右值引用,這總是合法的。你在做什麼的整體正確性取決於你如何處理結果std::move。您的示例代碼沒有任何問題。

問:這兩種情況有區別嗎?

// case 1        // case 2 
Type& ref = GetReference();   Type value = GetValue(); 
f(std::move(ref));     f(std::move(value)); 

唯一的區別是,在情況1中,ref是由GetReference()返回的對象的引用,但在情況2中,value是由GetValue()返回的對象的副本。