对于函数中返回临时对象时,现代C++编译器一般会支持返回值优化,减少临时对象的构造和析构。
比如:
Foo f()
{
Foo result;
//todo:(result);
return result;
}
就比我们刻意为之的代码:
Foo f()
{
Foo result;
//todo:(result);
return std::move(result);
}
更加合理,因为我们显式调用std::move()会阻止编译器对其进行RVO优化,而编译器的RVO优化实际上在函数内部绕过了对象的构造函数/析构函数等。因此我们刻意为之的版本实际效率不如第一个版本。
但有一个例外情况:
Foo read(Foo&& result) {
//...
return std::move(result);
}
当函数参数是一个右值引用时,将不符合NRVO的优化条件,编译器将不会为我们带来优化从而发生拷贝,因此我们需要显式调用std::move。
参考:https://stackoverflow.com/questions/17473753/c11-return-value-optimization-or-move
另外做一个复习:永远不要返回临时对象的引用。