2016-12-15 88 views
1

考慮const引用變量初始化

int foo() 
{ 
    return 1; 
} 

main() 
{ 
    const auto v1 = foo(); 
    const auto &v2 = foo(); 
} 

這兩個是const變量初始化之間的差異,包括性能的任何方面?有沒有比其他人更喜歡的情況?

+0

「不成熟的優化是萬惡的根源」 – Slava

+0

@Slava這整個語言都是關於微觀優化的。 – grisevg

+0

@grisevg我不同意。首先,不正確的程序速度有多快並不重要。所以首先是可讀性,然後是微型化,並且只在必要的地方。 – Slava

回答

0

const auto v1 = foo()

這會創建一個const變量v1。如上所述創建意味着任何foo()返回現在都保持在v1中。

const的汽車& V2 = FOO()

是一個const的引用,以便FOO()應返回的參考。如果任何foo()返回不支持移動語義const auto & v2會更快。

P.S.在你的情況下,因爲foo()返回一個int,所以不會有問題。

+0

正如我在回答中所說的那樣,在這種情況下'const auto&v2 = foo()'是非常危險的,應該避免,除非你想利用一個臨時的延長生命週期並且很好地理解它是如何工作的。 – grisevg

+1

在v2超出範圍之前,const引用的臨時變量不會被銷燬。檢查這個更多細節https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/ –

-1

我會小心,並避免const引用臨時(鏈接https://herbsutter.com/2008/01/01/gotw-88-a-c....讚美A.N.)。它可以很容易地更改爲auto &v2 = foo();這是未定義的行爲。

Scott Meyers和Herb Sutter建議根據值返回在堆棧上創建的對象。您可以使用命名返回值優化(NRVO)以確保最佳性能,實際上這將比returnig引用臨時或使用移動語義更快。

我並不是說永遠不會通過const引用來延長臨時對象的生命週期,我相信可能存在有用的用例,例如當NRVO無法完成時,我所說的就是避免除非有很好的理由。這不是很知名的功能,它可能會導致危險的代碼。

更新:更正const auto &v2 = foo();實際上是有效的代碼,但增加了解釋爲什麼它仍然應該避免。還添加了描述NRVO的鏈接。

+0

那麼爲什麼VS2012甚至不會發出警告呢? – user6386155

+1

沒有一個編譯器會抱怨,因爲它是一個常量。檢查這個https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/ –