简体   繁体   English

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

[英]Will an lvalue to rvalue conversion happen?

C++ Standard (4/5) the lvalue-to-rvalue conversion is not done on the operand of the unary & operator. C ++ Standard(4/5)左值和右值转换不是在一元&运算符的操作数上完成的。

For example: 例如:

int x;
int *p = &x;

In the above case, are p are &x both lvalues? 在上面的例子中, p&x两个左值? or What would be an appropriate example? 或者什么是恰当的例子?

Edit: 编辑:

What about this? 那这个呢?

int &r = x;

I'm sure there will be no conversion in this statement, but i'm confused how does & operator involve in this? 我确信在这个声明中不会有转换,但我很困惑&运营商如何参与其中?

The quote says that the conversion is not applied on the operand of unary & (in this case, x ). 引用说,转换不适用于一元& (在本例中为x )的操作数。 So the operand of & is an lvalue. 所以&的操作数是左值。

This is different from, say, the unary + operator. 这与一元+算子不同。 If you write +x , then lvalue-to-rvalue conversion is applied to the sub-expression x (with undefined behavior in this case, since x hasn't been initialized). 如果写+x ,然后左值到右值转换应用于子表达式x (在此情况下未定义的行为,因为x尚未初始化)。

Informally, "lvalue-to-rvalue conversion" means "reading the value". 非正式地,“左值到右值的转换”意味着“读取价值”。

The quote doesn't say anything about the result of & , which in fact is an rvalue. 引用没有说明&结果 ,实际上是一个右值。 In int *p = &x; int *p = &x; :

  • x is an lvalue, referring to the variable of that name, x是一个左值,指的是该名称的变量,
  • &x is an rvalue, it's part of the initializer (specifically, an assignment-expression ), &x是一个rvalue,它是初始化程序的一部分(具体来说,是赋值表达式 ),
  • p is neither an rvalue nor an lvalue, because it is not a (sub-)expression. p既不是右值也不是左值,因为它不是(子)表达式。 It's the name of the variable being defined. 它是正在定义的变量的名称。 In the C++ declarator grammar it's the declarator-id (8/4 in the C++03 standard). 在C ++声明符语法中,它是declarator-id (C ++ 03标准中的8/4)。

int &r = x; doesn't use the & address-of operator at all. 根本不使用& address-of运算符。 The & character in the declarator is just the syntax meaning that r is a reference-to-int, it's not taking the address of r . 声明符中的&字符只是语法,意思是r是对int的引用,它不是取r的地址。 In the C++ declarator grammar, it's actually called the ptr-operator . 在C ++声明语法中,它实际上称为ptr-operator

Think of lvalue as storage place and of rvalue as the value to store there. 可以将左值作为存储位置,将左值作为存储值。 Therefore *p is lvalue and &x is rvalue. 因此*p是左值, &x是右值。 However, & requires an lvalue as operand (x) but the result is a rvalue, but this does not change x itself. 但是,&需要左值作为操作数(x),但结果是右值,但这不会改变x本身。

The Standard quote basically says the operand on which & applies, doesn't become rvalue . 标准报价基本上说上操作数&适用,不会成为右值 It remains lvalue . 它仍然是左值

In fact, the operand of & cannot be rvalue . 实际上, &的操作数不能是rvalue It has to be lvalue , otherwise one would be able to get the address of a temporary object which is not allowed by the Standard: 它必须是左值 ,否则可以获得标准不允许的临时对象的地址:

struct A{};

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

It is precisely because the operand of & has to be lvalue , the above expressions are illegal, as the subexpressions int(10) and A() are rvalue expressions, for they create temporary objects. 正是因为&的操作数必须是左值 ,所以上面的表达式是非法的,因为子表达式int(10)A()rvalue表达式,因为它们创建临时对象。

Also note that even though the subexpression x in the expression &x is an lvalue , the result of applying & on x is an rvalue . 还要注意的是,即使子表达式x在表达式&x是一个左值 ,应用的结果&x是一个rvalue。 That is, the expression &x is an rvalue , and cannot appear on the right side of assignment operator: 也就是说,表达式&x是一个rvalue ,并且不能出现在赋值运算符的右侧:

&r = whatever; //illegal

I hope this helps you understanding the quote. 我希望这有助于您理解报价。


What about this? 那这个呢?

 int &r = x; 

This is okay. 这没关系。 Here & makes r a reference of object x . 这里&使r成为对象x的引用。 The & is not an operator here, and is not associated with the reference r , rather it is associated with the type. &这里不是运算符 ,并且与引用r无关,而是与类型相关联。 It is less confusing to write this as: 写这个不那么令人困惑:

int&  r = x;

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

"On the operand" should refer to the x on the right-hand-side. “在操作数上”应该是指右侧的x That is, the subexpression x in the statement int *p = &x; 也就是说,子表达式x在声明int *p = &x; is not an rvalue, but rather an lvalue. 不是左值,而是左值。 Contrast this to int a = b; 将此与int a = b;对比int a = b; , where the subexpression b is an rvalue (after conversion). ,其中子表达式b 一个右值(转换后)。

C++ Standard (4/5) the lvalue-to-rvalue conversion is not done on the operand of the unary & operator. C ++ Standard(4/5)左值和右值转换不是在一元&运算符的操作数上完成的。

This quote is there just to confuse you. 这句话只是为了让你迷惑。 It has no other purpose. 它没有其他目的。 ;) ;)

The most important quote is (quoting N3242, so the new terminology has "prvalue" instead of rvalue): 最重要的引用是(引用N3242,所以新术语有“prvalue”而不是rvalue):

Whenever a glvalue expression appears as an operand of an operator that expects a prvalue for that operand, the lvalue-to-rvalue (4.1), array-to-pointer (4.2), or function-to-pointer (4.3) standard conversions are applied to convert the expression to a prvalue. 每当glvalue表达式作为操作符的操作数出现时,该操作符需要该操作数的prvalue,左值到右值(4.1),数组到指针(4.2)或函数到指针(4.3)标准转换是用于将表达式转换为prvalue。

So the language could be described in term of constructs which expect a prvalue and constructs which do not. 因此,语言可以用期望prvalue的构造和不期望的构造来描述。 In particular, operator & does not "expect a prvalue" (quite the contrary), so the lvalue-to-rvalue implicit conversion is not necessary and won't be applied. 特别是,operator &不“期望prvalue”(恰恰相反),因此左值到右值的隐式转换不是必需的,也不会应用。

The standard description is not consistent: it never explicitly says that in x += y , the lvalue-to-rvalue implicit conversion is not applied to x , presumably because it extremely obvious. 标准描述不一致:它从未明确表示在x += y ,左值到右值的隐式转换不适用于x ,大概是因为它非常明显。 Why the authors felt the need to explicitly say that for &x , where it is equaly obvious, is beyond me. 为什么作者觉得有必要明确地说明对于&x来说,它是显而易见的,在我之外。

I think these mentions that implicit conversions are not applied should be removed. 我认为这些提到应该删除应用隐式转换。 The standard describe what happens, not the (infinitely many) things that do not happen (unless it is extremely surprising that it does not happen). 标准描述了所发生的事情,而不是(无限多的)未发生的事情(除非它不会发生,这是非常令人惊讶的)。

Implicit conversions are applied only to adjust the "nature" of an expression to the expectation of the context (context can be an expression, statement, declaration, ctor-init-list...). 隐式转换仅适用于将表达式的“性质”调整为对上下文的期望(上下文可以是表达式,语句,声明,ctor-init-list ...)。

What about this? 那这个呢?

int &r = x;

I'm sure there will be no conversion in this statement, 我相信在这个声明中没有转换,

because no implicit conversion is needed here. 因为这里不需要隐式转换。 Implicit conversion are applied only when needed. 仅在需要时应用隐式转换。 Reference binding does not expect a rvalue. 引用绑定不期望rvalue。

but i'm confused how does & operator involve in this? 但我很困惑&运营商如何参与其中?

It is not. 它不是。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM