在函數內返回一個臨時的容器對象是否需要手動的調用std::move, 編譯器會自動優化嗎?


會優化。但這種情況不會調用move的構造。現代編譯器會對此做優化,準確說是會發生拷貝消除(copy elison),copy elision的成本比低開銷的move還要低。參見:CG:Return containers by value 。 SO上也有不錯的解釋: answered by Nicol Bolas

示例:

vector& get_large_vector()
{
return ...;
}
// return by value is ok, most modern compilers will do copy elision
auto v = get_large_vector();

但是有例外情況,你的代碼對你的返回值加了const,這個時候不會發生優化。需要你移除const。參見: CG: F.20


準確說,推薦的做法是返回值時不要加std::move。

C++17及以上:拷貝省略 Copy elision - cppreference.com

C++11及以上:返回值優化(RVO, return value optimization)。這個規則超複雜,而且和編譯器支持有關。

加了std::move後會妨礙上面的優化。

不加std::move即使上面的優化不發生,(當返回的「變數」的生命周期在函數外失效時)也會進行move construction而非copy construction

-- 上面加粗部分舉個反向例子 --

struct stringstream {
//僅作示意,不代表std::stringstream內部結構
string str() const { return buf; }
string str() { return move(buf); } // C++20
//僅作示意,不代表std::stringstream內部結構
string buf;
};


一般編譯器會應用

RVO(Return Value Optimization)和NRVO(Named Return Value Optimization)規則

去掉2個臨時變數的構造和拷貝,直接在接收對象上進行構造, 所以不需要用到move語義。


編譯器會做優化

C++ Core Guidelines?

isocpp.github.io圖標

注意 如果函數返回加了const,會起反作用(返回容器加const本身也很奇怪)


不會,相當於多穿了個引用做返回值,直接輸出到引用上


瀉藥~

來學習一下


如果是成員變數,會自動返回引用


推薦閱讀:
相关文章