2015-11-03 37 views
0

假設一個函數的簽名存儲返回值作爲常量引用與作爲一種價值

std::string GetString(); 

,它通過返回值一個新的字符串。現在給出下面的代碼:

// (a) Store the return value to a const reference. 
const std::string& my_string = GetString(); 

// (b) Store the return value to a (const) value. 
const std::string my_string = GetString(); 

我是正確理解(a)和(b)是,從一個C++ 11編譯器的點,相同的?如果是這樣,對風格的選擇有一個大致的共識嗎?

+0

如果它們是相同的,我會感到驚訝。在情況b中,你實際上有一個std :: string。如果a,你有一個字符串的引用,但沒有實際的std :: string存儲。它應該會崩潰,甚至可能無法編譯。 –

+0

@ChrisBecke [This Q&A](http://stackoverflow.com/questions/2784262/does-a-const-reference-prolong-the-life-of--temporary)解釋了情況(a)。 –

+0

如何......意外。 –

回答

1

我正確地理解,從C++ 11編譯器的角度來看,(a)和(b)是相同的嗎?

不,它們不相同。 (a)延長GetString()返回的臨時對象的生命期。

(b)產生新的對象。它由以下構成:

  1. 通過使用GetString()作爲參數的返回值調用的std::string拷貝構造,
  2. 由RTO被分配的GetString()返回值,或
  3. 使用調用移動構造函數返回值爲GetString()
+0

一對夫婦:(a)不「延長臨時的生活」。由'GetString'的返回值創建的臨時消失了,並且(a)是對不再存在的臨時對象的引用。 (b)由於返回值優化(自永遠)或由於移動語義(C++ 11或更高版本),由'GetString()'構造的值直接移動到存儲器中時,可能會或可能不會調用複製構造函數在(b)中聲明而不調用複製構造函數。 – legalize

+0

@legalize,同意你(b),而不是(a)。參見[常量引用是否延長了臨時的生命期?](http://stackoverflow.com/questions/2784262/does-a-const-reference-prolong-the-life-of--temporary) –

+0

@R Sahu OK,我看到你對(a)的看法。然而,這感覺就像是一個難以記住的邊緣條件,而不是它要避免的。返回值優化/移動語義出現得更多,對理解IMO更有用。 – legalize

0

理論上它們是不同的,但實際上它們是相同的。您可以編寫的唯一代碼來說明差異將涉及decltype(my_string)

編譯器可以爲兩者生成相同的程序集。