複製elision是幾乎所有編譯器支持的允許優化。
複製elision意味着在某些情況下,創建一個臨時副本,然後將該臨時副本複製到一個命名變量中,然後銷燬該臨時副本,可能會導致直接構造該變量。
與返回值優化和移動語義一起,這意味着返回可移動的複雜對象是有效的。對於類似於int
的類型,as-if規則也處於運行狀態:編譯器可以執行任何表現爲 - 如果執行了代碼行或代碼塊的任何行爲,並且編譯器瞭解在複製/移動周圍(即,基本上什麼都沒有),所以他們可以跳過這些複製/移動。
爲了確保RVO和複製省略發生得當,你想要做這樣的事情:
int function() {
int retval = 8; // create the return value in one spot, this makes NRVO possible
// code goes here
return retval; // you can have more than one return statement in most compilers
}
int result = function(); // initialize the variable result by assigning the return value of the function to it.
如果你做到以上,大多數編譯器將直接在result
變量存儲構建retval
對象,與沒有副本在所有如果function
的身體可以在result
可以看到存在的(有些人可能做到這一點,即使你看不到function
mayhap體)
在C++ 11個還有其他招數。
int function() {
return {7}; // guaranteed to directly construct the return value without a copy
}
int result = function(); // even if copy elision is not done, the temporary `int` is moved into `result`.
如果您阻止複製省略:
int function() {
int foo = 7;
int bar = 3;
// code
if (foo>bar)
return foo;
else
return bar;
}
,只要你返回一個局部變量,隱含的舉動出現。你也可以明確地將std::move
納入返回值。
現在,對於像int
這樣簡單小巧的類型,所有這些優化都是毫無意義的。當你在處理更大,更昂貴的對象時,如std::vector
的std::vector
s,它們中的每一個都有10MB的數據,這些技術意味着返回的值最終會像傳遞指針一樣高效,以便仔細填充。
任何選項都可以根據優化進行...正如你所說的按價值回報更合乎邏輯,你應該堅持這一點..更好的方法 – sethi