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

时间:2009-07-12 18:44:44

标签: c++ c++11 rvalue-reference

例如:

Beta_ab&&
Beta::toAB() const {
    return move(Beta_ab(1, 1));
}

2 个答案:

答案 0 :(得分:204)

Beta_ab&&
Beta::toAB() const {
    return move(Beta_ab(1, 1));
}

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

Beta_ab
Beta::toAB() const {
    return Beta_ab(1, 1);
}

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

Beta_ab ab = others.toAB();

它会将临时构造移动到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); }
};

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

Beta_ab ab = Beta().getAB();

答案 1 :(得分:3)

可以更高效,例如,在不同的背景下:

template <typename T>
T&& min_(T&& a, T &&b) {
    return std::move(a < b? a: b);
}

int main() {
   const std::string s = min_(std::string("A"), std::string("B"));
   fprintf(stderr, "min: %s\n", s.c_str());
   return 0;
}

有趣的是,在我的计算机上clang++ -O3会为上面的代码生成54条指令,而针对常规std::min生成62条指令。但是,对于-O0,它会针对上面的代码生成518条指令,而针对常规std::min生成481条。