2016-12-03 95 views
7

比方說,我們有這種情況RVO是否適用於這種情況?

std::string v_1() 
{ 
    return "name"; 
} 
std::string test = v_1(); 

是RVO應用在這裏?我認爲答案是否定的,因爲應用RVO的規則是:「如果一個函數按值返回一個類的類型,並且return語句的表達式是一個非自動存儲持續時間的非易失性對象的名稱,函數參數或catch子句參數與具有相同類型(忽略頂級cv資格)作爲函數的返回類型,則複製/移動被省略「 而在這種情況下返回的對象沒有相同類型的函數的返回類型,但我不是100%,RVO不適用於此處。

非常感謝。

PS。在這次演講中https://www.youtube.com/watch?v=AKtHxKJRwp4(分鐘40,第18次)來自微軟的Stephan談到了RVO無法應用的情況,因爲函數的返回類型與返回對象的類型不同(在他的例子中是一個元組與一對)。我認爲這裏適用同樣的原則。

+3

它大部分等價於'return std :: string(「name」)'...... – Jarod42

+0

返回的結果是* not * const char *'... – user268396

+0

@ user268396你是對的,但是在大多數情況下案例(也在這裏)它被隱式轉換爲一個之前轉換爲字符串... :) –

回答

5

我覺得你很困惑NRVORVO

  • NRVO - 命名返回值優化
  • RVO - (未命名)返回值優化

NRVO涉及命名的變量,而RVO包括那些在return聲明構造無名的臨時。

上的視頻的示例是NRVO其中命名對象顯然不能呼叫者堆棧當類型是不同的,因爲必須存在一種類型的一個對象中的函數的堆棧和另一個上構建調用者堆棧上的另一種類型的對象。

你的例子是RVO你沒有使用預先構造的命名對象。在你的代碼中,你是構造 a 臨時對象作爲返回值。因爲它是臨時您引用的規則不適用。

按照C++11標準我看不出有什麼理由不能發生RVO

12.8複製和移動類對象[ class.copy ] ... ...

- 當一個臨時類對象還沒有出現d參考(12。2)將被複制/移動 用相同的CV-非限定類型的一類對象中,複製/移動操作可以通過 直接構建臨時物體插入省略副本的目標可以省略/移動

通過返回char array構造了一個臨時std::string,並且是返回給調用者的東西。

3

NRVO和RVO是elision的不同情況。

Elision是將多個對象的生命週期合併爲一個對象的地方。

名稱NRVO和RVO是編譯器在標準允許時如何進行省略的名稱。

省音被允許在該return行,函數的返回值創建的臨時之間你的榜樣,並命名變量你存儲在返回值。每一個嚴肅的編譯器可以和會的Elid這些值加在一起,除非你明確地告訴它不要通過編譯器標誌。而在C++ 17中,這些選擇將是強制性的。

相關問題