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

问题描述 投票:1回答:2

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

class Obj {};

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

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

o2(左值引用)如何能够引用似乎是右值的东西?

c++ c++11 reference rvalue lvalue
2个回答
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


8
投票

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

不,因为函数调用的结果并不总是rvalue。

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

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

我很确定这条规则专门用于避免您的问题所引发的问题。

© www.soinside.com 2019 - 2024. All rights reserved.