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

Is an lvalue reference returned from a function actually an rvalue (from the perspective of the caller)?

本文关键字:调用者 返回 函数 引用 实际上      更新时间:2023-10-16

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

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

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

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

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

来自 [expr.call]/14(强调我的(:

如果结果类型是左值引用类型或对函数类型的右值引用,则函数调用

为左值;如果结果类型是对对象类型的右值引用,则函数调用为 x值;否则为属性值。

我很确定这条规则的存在是为了避免你的问题所问的问题。

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

  • 左值 = 具有标识且不可移动
  • X值 = 具有标识和是可移动的
  • Rvalue = 没有标识且可移动

refToRef 通过左值引用返回,因此 refToRef(o) 引用的Obj是具有标识的对象(&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