2017-08-03 35 views
0
std::string my_func(){ 
    return std::string("..."); 
} 

std::string可以替換爲std::vector或其他任何東西。一般來說,我如何知道rv已被移動並且未被複制?我如何知道rv已被移動且未被複制?

+2

讀取生成的彙編語言代碼。 –

+0

它可能根本不會被移動或複製。 – juanchopanza

+0

它被移動或複製。答案是重要的,因爲我堅持寫的東西,如果它被移動,我寧願寫'void my_func(std :: string & str);'而不是如果它不 – user3600124

回答

2

移動構造函數接受右值引用。在處理prvalues時,右值引用優於對const的左值引用。所以,只要你的類型有一個有效的移動構造函數,編譯器就會選擇移動構造函數,並且只有在沒有移動構造函數時纔會回退到複製構造函數。

這就是說在這種情況下很可能沒有任何東西會被複制或移動,並且RVO將會在其中直接在呼叫站點構建對象。要知道它是否唯一的方法是檢查組件。

從C++ 17開始,使用guaranteed copy elision確保您確實無法複製或移動。

5

cppreference

在C++ 11,表達式...... 沒有身份,可以從被稱爲prvalue( 「純右值」)表達式中移動。

的臨時對象,像您正在返回的一個(std::string("..."))沒有身份,並且可以從,因爲編譯器可以檢測到它的狀態也不會其壽命結束之前被使用來移動。因此,編譯器寧願移動該對象來複制它。

然而,臨時對象很可能無法移動或複製,因爲在所有的返回值優化(RVO)copy elision優化該構造對象,它本來被移動到存儲形式。因此,如果您要編寫std::string str = my_func();,代碼可能會進行優化,以便在原地構建str"...",而不是在my_func()內構建一個字符串,然後將其移出。 RVO適用於任何可複製和/或可移動的物體。

相關問題