是否需要临时或文字来获得右值?

时间:2012-11-03 01:12:36

标签: c++ temporary rvalue

This question询问所有临时值是否为右值。

答案是否定的,因为如果我们考虑这个表达式:

const int &ri = 2 + 3;

然后,可以使用非常相同的临时(2 + 3),这是一个右值 作为后续表达式中的左值:

const int *pi = &ri;

所以这个临时不是(仅)一个右值。

然后逻辑语句temporary ==> rvalue为假。

但是,我们不能写

const int &ri = &(2 + 3); // illegal, 2 + 3 -> temporary -> rvalue

int *i = &4; // illegal, 4 is an rvalue (literal)

int foo();
int *i = &foo(); // illegal, foo() -> temporary -> rvalue

因此我的问题是,我们能否在某个表达式中生成一个rvalue而没有 有临时或文字? rvalue ==> (temporary or literal)是真的吗?

2 个答案:

答案 0 :(得分:5)

产生临时对象的表达式是 r值。有一个特殊的规则允许const引用和r值引用绑定到r值,这会将临时对象的生命周期延长到引用的生命周期(见12.2(5)),但这不会使临时-object表达式中任何较小的r值。

但是,一旦绑定到引用,引用变量本身就有一个名称,因此引用表达式是l-lvalue。

不要混淆表达式,变量和对象。

答案 1 :(得分:3)

rvalue lvalue 属性适用于表达式,而不适用于对象。表达式可以是左值右值。过度简化产生值的表达式是 rvalue-expression ,产生对象的表达式是 lvalue-expression 左值 rvalue 转换是读取对象的值的行为。

产生临时和文字的表达式都是 rvalue-expressions ,它们代表而不是实际对象。

在你的例子中:

const int &ri = 2 + 3;
const int *pi = &ri;

表达式2+3是用于初始化常量引用的 rvalue-expression 。根据语言,这意味着临时超出当前表达式的延长,直到引用超出范围。之后,在第二个表达式中,子表达式ri是一个左值表达式,它引用临时对象,其生命周期已被扩展。

请注意,还有其他方法可以创建带有临时值的 rvalue表达式,例如调用一个产生引用的成员:

struct test {
   test& thisTest() { return *this; }
};
test foo();
... foo().thisTest()

子表达式foo() rvalue-expression ,但表达式foo().thisTest()左值表达式。它们都引用了一个临时对象,它将在完整表达式的末尾消失。