在函数内返回一个临时的容器对象是否需要手动的调用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本身也很奇怪)


不会,相当于多穿了个引用做返回值,直接输出到引用上


泻药~

来学习一下


如果是成员变数,会自动返回引用


推荐阅读:
相关文章