是否会发生左值转换的左值?

时间:2011-12-13 11:41:27

标签: c++ implicit-conversion lvalue rvalue lvalue-to-rvalue

  

C ++标准版(4/5)未对左值进行左值到右值的转换   一元&的操作数操作

例如:

int x;
int *p = &x;

在上述情况下,p&x两个左值吗?或者什么是恰当的例子?

修改

这个怎么样?

int &r = x;

我确定此声明中没有转换,但我很困惑& amp;运营商涉及到这个?

5 个答案:

答案 0 :(得分:4)

引用说明转换不适用于一元&的操作数(在本例中为x)。所以&的操作数是左值。

这与一元+运算符不同。如果你写+x,那么左值转换 应用于子表达式x(在这种情况下具有未定义的行为,因为x没有没有初始化。

非正式地,“左值到右值的转换”意味着“读取价值”。

引用没有说明&结果,实际上它是一个右值。在int *p = &x;

  • x是一个左值,指的是该名称的变量
  • &x是一个右值,它是初始化程序的一部分(具体来说,是赋值表达式),
  • p既不是右值也不是左值,因为它不是(子)表达式。它是正在定义的变量的名称。在C ++声明符语法中,它是 declarator-id (C ++ 03标准中的8/4)。

int &r = x;根本不使用&地址运算符。声明符中的&字符只是语法意味着r是对int的引用,它不是r的地址。在C ++声明符语法中,它实际上称为 ptr-operator

答案 1 :(得分:2)

将左值作为存储位置,将左值作为存储值。因此*p是左值,&x是左值。然而,&需要左值作为操作数(x),但结果是右值,但更改x本身。

答案 2 :(得分:1)

标准引用基本上表示&适用的操作数,不会成为 rvalue 。它仍然是左值

实际上,&的操作数不能是 rvalue 。它必须是 lvalue ,否则将能够获得标准不允许的临时对象的地址:

struct A{};

int *addressOfTemporary_int_object = &(int(10)); //error
A *addressOfTemporary_A_object = &A(); //error

正是因为&的操作数必须是 lvalue ,所以上述表达式是非法的,因为子表达式int(10)A() rvalue 表达式,用于创建临时对象。

另请注意,即使表达式x中的子表达式&x左值,在&上应用x的结果仍然是一个 rvalue 。也就是说,表达式&x rvalue ,并且不能出现在赋值运算符的右侧:

&r = whatever; //illegal

我希望这可以帮助您理解报价。


  

这个怎么样?

int &r = x;

这没关系。此处&使r成为对象x的引用。这里&不是运算符,并且与引用r无关,而是与类型相关联。将其写成以下内容并不那么令人困惑:

int&  r = x;

//Or if you use typedef as
typedef int& intref;
intref r = x;

答案 3 :(得分:0)

“在操作数上”应该引用右侧的x。也就是说,语句x中的子表达式int *p = &x; 不是是一个右值,而是一个左值。将其与int a = b;进行对比,其中子表达式b 是一个右值(转换后)。

答案 4 :(得分:0)

  

C ++ Standard(4/5)左值和右值的转换不是在一元&的操作数上完成的。操作

这句话只是为了让你迷惑。它没有其他目的。 ;)

最重要的引用是(引用N3242,所以新术语有“prvalue”而不是rvalue):

  

每当glvalue表达式作为操作符的操作数出现时,该操作符需要该操作数的prvalue,lvalue-to-rvalue(4.1),array-to-pointer(4.2)或function-to-pointer(4.3)应用标准转换以将表达式转换为prvalue。

因此,语言可以用期望prvalue和没有的结构的构造来描述。特别是,运算符&不会“期望prvalue”(恰恰相反),因此左值到右值的隐式转换不是必需的,也不会应用。

标准描述不一致:它从未明确表示在x += y中,左值到右值的隐式转换不适用于x,大概是因为它非常明显。为什么作者觉得有必要明确地说明&x,这在我看来是非常明显的。

我认为这些提及隐含的转化应该被删除。标准描述了发生了什么,而不是(无限多)没有发生的事情(除非它不会发生,这是非常令人惊讶的。)

隐式转换仅适用于将表达式的“性质”调整为对上下文的期望(上下文可以是表达式,语句,声明,ctor-init-list ...)。

  

这个怎么样?

     

int &r = x;

     

我确信此声明中没有转换,

因为此处不需要隐式转换 。仅在需要时应用隐式转换。参考绑定不期望rvalue。

  

但是我很困惑&运营商涉及到这个?

不是。