从函数返回的左值引用实际上是右值(从调用者的角度来看)吗?

时间:2019-04-15 15:06:24

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

如何使左值引用引用从函数返回的左值引用?从调用者的角度来看,从该函数返回的左值引用实际上不是右值吗?例如:

class Obj {};

Obj& refToRef(Obj& o) {
    return o;
}

int main() {
    Obj o;
    Obj& o2 = refToRef(o);
}

o2(左值引用)如何能够引用看似右值的内容?

2 个答案:

答案 0 :(得分:8)

  

从调用者的角度来看,从该函数返回的左值引用实际上不是右值吗?

否,因为函数调用的结果并非总是 一个右值。

来自[expr.call]/14(重点是我):

  

如果结果类型是左值引用类型或函数的右值引用,则函数调用是左值;如果结果类型是对对象类型的右值引用,则函数调用是左值;并且prvalue否则。

我很确定这条规则是专门为避免您的问题所问的问题而存在的。

答案 1 :(得分:1)

在考虑表达的价值,身份和移动能力时,请牢记两个属性。如果表达式具有名称或地址,则它具有标识;如果表达式被求值,表达式将过期,则该表达式是可移动的。

  • 左值=具有身份且不可移动
  • Xvalue =具有标识和 可以移动
  • Rvalue =没有身份并且可以移动

refToRef通过左值引用返回,因此,Obj所引用的refToRef(o)是具有标识(定义了&refToRef(o))的对象,并且在对表达式求值后仍会存在。 refToRef(o)因此是左值。

此外,请注意不要将类型与价值混淆。如果我添加了一个按值返回并从中创建右值引用的函数,则右值引用将是一个左值。例如

class Obj {};
Obj& refToRef(Obj& o) {
    return o;
}

Obj refToVal(Obj& o) {
    return o;
}
int main() {
    Obj o;
    Obj& o2 = refToRef(o);
    Obj&& o3 = refToVal(o);
}

o3的类型为rvalue refernce to Obj,表达式为lvalue