通过右值参考返回更有效吗?

Nei*_*l G 119 c++ rvalue-reference c++11

例如:

Beta_ab&&
Beta::toAB() const {
    return move(Beta_ab(1, 1));
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*itb 223

Beta_ab&&
Beta::toAB() const {
    return move(Beta_ab(1, 1));
}
Run Code Online (Sandbox Code Playgroud)

这将返回一个悬空引用,就像左值引用案例一样.函数返回后,临时对象将被破坏.您应该Beta_ab按值返回,如下所示

Beta_ab
Beta::toAB() const {
    return Beta_ab(1, 1);
}
Run Code Online (Sandbox Code Playgroud)

现在,它正确地将临时Beta_ab对象移动到函数的返回值中.如果编译器可以,它将通过使用RVO(返回值优化)完全避免移动.现在,您可以执行以下操作

Beta_ab ab = others.toAB();
Run Code Online (Sandbox Code Playgroud)

并且它将构建临时构造ab,或者做RVO以省略完全移动或复制.我建议你阅读BoostCon09 Rvalue References 101,它解释了这个问题,以及(N)RVO如何与之相互作用.


在其他情况下,返回右值参考的情况是个好主意.想象一下,你有一个getAB()经常在临时调用的函数.使它返回rvalue临时值的常量参考值并不是最佳的.你可以像这样实现它

struct Beta {
  Beta_ab ab;
  Beta_ab const& getAB() const& { return ab; }
  Beta_ab && getAB() && { return move(ab); }
};
Run Code Online (Sandbox Code Playgroud)

请注意,move在这种情况下不是可选的,因为ab既不是本地自动也不是临时右值.现在,ref-qualifier &&说第二个函数是在rvalue temporaries上调用的,进行了以下移动,而不是复制

Beta_ab ab = Beta().getAB();
Run Code Online (Sandbox Code Playgroud)

  • 当返回类型是r值引用时,我一直认为悬空引用问题会自动消失.很高兴我咬了它之前就把它弄直了.堆栈粉碎臭虫吮吸. (49认同)
  • :)实际上,rvalue引用是"仅仅引用",就像左值引用一样.他们不复制或存储任何东西. (26认同)
  • 成员函数的const和限定符比简单的const更多吗? (9认同)
  • + 1-ed,但链接断开:[BoostCon09 Rvalue References 101](https://www.boostpro.com/trac/wiki/BoostCon09/RValue101) (4认同)
  • @galinette这些是[ref-qualifiers](http://en.cppreference.com/w/cpp/language/member_functions). (3认同)
  • @ JohannesSchaub-litb我试过"Beta_ab && getAB()..."和"Beta_ab getAB()..."(在返回类型中有和没有&&).他们产生了同样的结果.这&&真的有必要吗? (3认同)
  • @NeilG有两组&&,一组在返回类型旁边,一组在声明的末尾.第二个集合意味着应该在rvalue上调用该函数.我问第一集.我错过了什么? (2认同)
  • @CandyChiu 我建议您创建一个新的 SO 问题并在那里提出您的问题,并询问诸如“&& 之间的差异和&& 限定函数的无引用”之类的问题。 (2认同)