1

这个问题询问是否所有临时对象都是右值。

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

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 ==> (temporary or literal)真的吗?

4

2 回答 2

5

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

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

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

于 2012-11-03T01:21:24.023 回答
3

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

产生临时值和文字的表达式都是右值表达式,它们表示而不是实际对象。

在您的示例中:

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

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

请注意,还有其他方法可以使用临时变量创建右值表达式,例如调用产生引用的成员:

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

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

于 2012-11-03T02:15:16.210 回答