左值參考的右值參考是否合法?左值參考的左值參考值左值/右值的右值參考值
考慮下面的例子,最終的rvalueRef中的兩種情況在引用或類型(或其他事物)方面是否有區別?
Type& ref = GetReference()
Type&& rvalueRef = std::move(ref)
vs
Type value = GetValue()
Type&& rvalueRef = std::move(value)
左值參考的右值參考是否合法?左值參考的左值參考值左值/右值的右值參考值
考慮下面的例子,最終的rvalueRef中的兩種情況在引用或類型(或其他事物)方面是否有區別?
Type& ref = GetReference()
Type&& rvalueRef = std::move(ref)
vs
Type value = GetValue()
Type&& rvalueRef = std::move(value)
這兩個代碼都是正確的,在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:如果這樣做,這是沒有任何差別。只有演員在那裏。爲了實際移動,應該有一個適當的目標類型,可以調用移動構造函數或移動賦值!在你的情況下,沒有任何一個的調用。
問:有一個右值引用右值引用是合法嗎?
這不是你問的問題。您真正要問的問題是這樣的:
問:將左值引用轉換爲右值引用是合法嗎?
答案是肯定的。 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()
返回的對象的副本。