CppCoreGuidelines F.48 不要这样写 return std::move(local)
06 July 2022
F.48: Don’t return std::move(local)
理由
因为C++有复制省略机制,在返回值的时候就不需要std::move
了。
在返回语句中,如果返回的是一个自动存储区的非 volatile
对象;并且该对象不是函数参数,不是 catch
语句的参数;并且对象类型和返回值的类型一样(不考虑 const
和 volatile
修饰符)。那么编译器就会使用复制省略机制,避免复制构造一个新的对象。这种机制叫“有名称的返回值优化(Named Return
Value Optimization,简称 NRVO)”。
例子
// -*- compile-command: "g++ -std=c++20 code.cpp && ./a"; -*- #include <iostream> #include <gsl/gsl> using namespace std; using namespace gsl; struct S { int m_i; S(int i) : m_i(i) {} }; ostream& operator<<(ostream &o, S s) { o << s.m_i; return o; } S f() { S result{11}; return std::move(result); } int main() { cout << f(); return 0; }
11
例子
// -*- compile-command: "g++ -std=c++20 code.cpp && ./a"; -*- #include <iostream> #include <gsl/gsl> using namespace std; using namespace gsl; struct S { int m_i; S(int i) : m_i(i) {} }; ostream& operator<<(ostream &o, S s) { o << s.m_i; return o; } S f() { S result{11}; return result; } int main() { cout << f(); return 0; }
address of result: 0x381ffff70c 11
强化
最好通过工具确保合理的返回表达式