2014-02-11 54 views
4

我是C++ 11的新手,在閱讀C++11 FAQ時遇到以下問題。函數的右值引用和返回值

假設我們有一個函數f()返回在X類型的值,那麼我們有以下的方法來存儲它的返回值:

X a = f(); // copy assignment 
X&& b = f(); // move assignment 

C++ FAQ,第二個避免了不必要的副本。

我的問題是:第二個始終是接收函數調用返回值的首選方法?另外,auto c = f();是否等同於上述任務之一?謝謝。

回答

5

您錯誤地標記線。它們都不是任務,更不用說分別複製和移動任務。相反,第一個涉及複製/移動構造(取決於X是否有移動構造函數),第二個僅僅是初始化引用。

接收函數調用的返回值的首選方式是第一種方式:

X a = f(); 

從臨時由f()返回到對象a副本幾乎肯定會被省略。這與auto c = f();將採用的形式相同。

第二個應該很少出現在你的代碼中。您正在對返回類型f()進行右值參考。 Stroustrup僅僅是爲了證明臨時對象可以綁定到右值引用。當您調用具有右值引用參數類型的移動構造函數/賦值運算符時,這在實際代碼中經常發生。

+0

哦,是的,他們不是任務,他們創造的東西。非常感謝您指出我的錯誤並提供寶貴的答案! – keelar

+0

那麼第二個不會保存任何操作(如複製)呢?本來我認爲第二個只是簡單地從'f()'返回而不創建新事物。我能知道我在哪裏可能會錯/錯過嗎? – keelar

+1

@keelar你是對的,將不會有副本。它只是綁定對返回對象的引用。但是很可能,第一個也不會有任何副本。 –

4
  1. 無的你寫的是一個賦值。所有的代碼段聲明並初始化一個新的變量。

  2. auto a = f()相同X a = f()

  3. X && b是一個參考,而不是一個對象。

  4. 總是創建一個本地對象變量,即X a = f(),從來沒有右值引用。後者幾乎沒有一個好的理由。無論哪種情況,只要變量確實存在,就會生存一個對象,並且不需要額外的複雜性。

+0

非常感謝您指出我的錯誤並提供詳細的答案! – keelar