如何使左值引用引用从函数返回的左值引用?从调用者的角度来看,从该函数返回的左值引用实际上不是右值吗?例如:
class Obj {};
Obj& refToRef(Obj& o) {
return o;
}
int main() {
Obj o;
Obj& o2 = refToRef(o);
}
o2
(左值引用)如何能够引用看似右值的内容?
答案 0 :(得分:8)
从调用者的角度来看,从该函数返回的左值引用实际上不是右值吗?
否,因为函数调用的结果并非总是 一个右值。
来自[expr.call]/14(重点是我):
如果结果类型是左值引用类型或函数的右值引用,则函数调用是左值;如果结果类型是对对象类型的右值引用,则函数调用是左值;并且prvalue否则。
我很确定这条规则是专门为避免您的问题所问的问题而存在的。
答案 1 :(得分:1)
在考虑表达的价值,身份和移动能力时,请牢记两个属性。如果表达式具有名称或地址,则它具有标识;如果表达式被求值,表达式将过期,则该表达式是可移动的。
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
。