2013-01-20 78 views
6

比方說,我有功能C++編譯器可以爲常量返回值執行RVO嗎?

#include <string> 

std::string const foo() 
{ 
    std::string s = "bar"; 
    return s; 
} 

int main() 
{ 
    std::string t = foo(); 
} 

可以執行(命名)返回值優化t,即使類型st是從foo返回類型都不同,由於const編譯器差異?

(如果答案是C++ 03和不同的C++ 11然後我在知道C++ 03的回答很有興趣。)

+0

爲什麼不包含至少一個編譯器的實驗結果? –

+0

@MarcGlisse:好吧,Visual C++ 2008優化了它,但我不確定標準是否真的允許它。 – Mehrdad

回答

7

沒有辦法對RVO優化打破承諾一個const,所以沒有問題:可以執行RVO。


然而,移動語義const影響。它有效地禁用移動語義,也就是調用構造函數或移動賦值操作符。所以一般來說,不要在返回值上使用const

Scott Meyers最初推薦const關於返回值,以獲得更多理智的編碼。

然後Andrei Alexandrescu在他的DDJ的Mojo文章中指出,從今以後,在移動語義上,返回值的const應該更好地被禁止,並且Scott早先的建議被忽略。


現在我從來沒有費心去學習各種專門的RVO縮略語,如NRVO等。一個主要原因是這些中途改變了含義,最初在g ++編譯器中有一些自定義功能的含義。這裏的術語只是一團糟。

所以,如果我的術語錯了,我真的應該使用其他一些縮寫詞,那麼請隨時糾正! :-)

+0

+1關於移動語義的好處,儘管它確實讓我想知道:那麼禁用帶有const返回值的移動語義有什麼問題?不是RVO(完全避免實例化一個對象)比移動更好(它仍然需要實例化對象並執行維護工作才能執行實際移動)? – Mehrdad

+0

@Mehrdad:移動語義受程序員控制,編譯器沒有發言權,而RVO處於編譯器控制下,程序員幾乎沒有發言權。例如,調用可能是一個賦值's = foo()'而不是初始化。那麼'const'可以防止移動函數字符串結果的緩衝區:它很可能被複制,可能還有另一個緩衝區被分配。 –

+0

好的,但*如果*我知道RVO正在發生,它將*永遠不會*(實際上)比移動慢,對吧?所以在性能方面,如果你能確保RVO,那麼返回'const'比返回可變嗎? – Mehrdad

相關問題