我是C++ 11的新手,在閱讀C++11 FAQ時遇到以下問題。函數的右值引用和返回值
假設我們有一個函數f
()返回在X
類型的值,那麼我們有以下的方法來存儲它的返回值:
X a = f(); // copy assignment
X&& b = f(); // move assignment
據C++ FAQ,第二個避免了不必要的副本。
我的問題是:第二個始終是接收函數調用返回值的首選方法?另外,auto c = f();
是否等同於上述任務之一?謝謝。
我是C++ 11的新手,在閱讀C++11 FAQ時遇到以下問題。函數的右值引用和返回值
假設我們有一個函數f
()返回在X
類型的值,那麼我們有以下的方法來存儲它的返回值:
X a = f(); // copy assignment
X&& b = f(); // move assignment
據C++ FAQ,第二個避免了不必要的副本。
我的問題是:第二個始終是接收函數調用返回值的首選方法?另外,auto c = f();
是否等同於上述任務之一?謝謝。
您錯誤地標記線。它們都不是任務,更不用說分別複製和移動任務。相反,第一個涉及複製/移動構造(取決於X
是否有移動構造函數),第二個僅僅是初始化引用。
接收函數調用的返回值的首選方式是第一種方式:
X a = f();
從臨時由f()
返回到對象a
副本幾乎肯定會被省略。這與auto c = f();
將採用的形式相同。
第二個應該很少出現在你的代碼中。您正在對返回類型f()
進行右值參考。 Stroustrup僅僅是爲了證明臨時對象可以綁定到右值引用。當您調用具有右值引用參數類型的移動構造函數/賦值運算符時,這在實際代碼中經常發生。
無的你寫的是一個賦值。所有的代碼段聲明並初始化一個新的變量。
auto a = f()
相同X a = f()
X && b
是一個參考,而不是一個對象。
總是創建一個本地對象變量,即X a = f()
,從來沒有右值引用。後者幾乎沒有一個好的理由。無論哪種情況,只要變量確實存在,就會生存一個對象,並且不需要額外的複雜性。
非常感謝您指出我的錯誤並提供詳細的答案! – keelar
哦,是的,他們不是任務,他們創造的東西。非常感謝您指出我的錯誤並提供寶貴的答案! – keelar
那麼第二個不會保存任何操作(如複製)呢?本來我認爲第二個只是簡單地從'f()'返回而不創建新事物。我能知道我在哪裏可能會錯/錯過嗎? – keelar
@keelar你是對的,將不會有副本。它只是綁定對返回對象的引用。但是很可能,第一個也不會有任何副本。 –