C++11之後返回std::vector時會自動調用std::move嘛?
在函數內返回一個臨時的容器對象是否需要手動的調用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本身也很奇怪)
不會,相當於多穿了個引用做返回值,直接輸出到引用上
瀉藥~
來學習一下
如果是成員變數,會自動返回引用
推薦閱讀: