Произойдет ли преобразование lvalue в rvalue? - PullRequest
3 голосов
/ 13 декабря 2011

C ++ Standard (4/5) преобразование lvalue в rvalue не выполняется на операнд унарного & оператора.

Например:

int x;
int *p = &x;

В приведенном выше случае p равны ли &x оба значения? или какой будет подходящий пример?

Изменить:

А как насчет этого?

int &r = x;

Я уверен, что в этом утверждении не будет преобразования, но я запутался, как оператор & в этом участвует?

Ответы [ 5 ]

4 голосов
/ 13 декабря 2011

Цитата говорит, что преобразование не применяется к операнду с одинарным & (в данном случае x).Таким образом, операнд & является lvalue.

Это отличается, скажем, от унарного оператора +.Если вы напишите +x, тогда преобразование lvalue в rvalue будет применено к подвыражению x (с неопределенным поведением в этом случае, поскольку x не было инициализировано).

Неформально «преобразование lvalue в rvalue» означает «чтение значения».

Цитата ничего не говорит о результате из &, которыйна самом деле это ценность.В int *p = &x;:

  • x - это lvalue, ссылаясь на переменную с таким именем,
  • &x - это rvalue, это часть инициализатора (в частности, выражение-присваивание ),
  • p не является ни значением, ни значением, поскольку оно не является (под) выражением.Это имя определяемой переменной.В грамматике декларатора C ++ это идентификатор объявления (8/4 в стандарте C ++ 03).

int &r = x; не использует адрес &оператора вообще.Символ & в объявителе - это просто синтаксис, означающий, что r является ссылкой на int, он не принимает адрес r.В грамматике декларатора C ++ это на самом деле называется оператор ptr .

2 голосов
/ 13 декабря 2011

Думайте о lvalue как о месте хранения, а о rvalue - как о значении для хранения там. Следовательно, *p является lvalue, а &x является rvalue. Однако & требует lvalue в качестве операнда (x), но результат является rvalue, но этот не не меняет x сам по себе.

1 голос
/ 13 декабря 2011

Стандартная цитата в основном говорит, что операнд, к которому применяется &, не становится rvalue . Осталось lvalue .

Фактически, операнд & не может быть rvalue . Это должно быть lvalue , иначе можно было бы получить адрес временного объекта, который не разрешен Стандартом:

struct A{};

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

Именно потому, что операнд & должен быть lvalue , приведенные выше выражения недопустимы, так как подвыражения int(10) и A() являются rvalue выражениями, ибо они создают временные объекты.

Также обратите внимание, что, хотя подвыражение x в выражении &x является lvalue , результат применения & к 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;
0 голосов
/ 25 декабря 2011

C ++ Standard (4/5) преобразование lvalue в rvalue не выполняется для операнда унарного оператора &.

Эта цитата предназначена только для того, чтобы сбить вас с толку.У него нет другой цели.;)

Самая важная кавычка (цитирование N3242, поэтому в новой терминологии вместо rvalue вместо «значение» указано «prvalue»):

Всякий раз, когда выражение glvalue появляется в качестве операнда операторакоторый ожидает prvalue для этого операнда, стандартные преобразования lvalue-to-rvalue (4.1), array-to-pointer (4.2) или function-to-pointer (4.3) применяются для преобразования выражения в значение prvalue.

Таким образом, язык может быть описан в терминах конструкций, которые ожидают значения, и конструкций, которые этого не делают.В частности, оператор & не «ожидает prvalue» (скорее наоборот), поэтому неявное преобразование lvalue в rvalue не является необходимым и не будет применяться.

Стандартное описание ненепротиворечиво: в нем явно не говорится, что в x += y неявное преобразование lvalue-в-значение не применяется к x, вероятно, потому, что оно чрезвычайно очевидно.Почему авторы почувствовали необходимость прямо сказать, что для &x, где это в равной степени очевидно, я не понимаю.

Я думаю, что эти упоминания о том, что неявные преобразования не применяются, должны быть удалены,Стандарт описывает, что происходит, а не (бесконечно много) вещей, которые не происходят (если только не удивительно, что этого не происходит).

Неявные преобразования применяются только для корректировки «природы» выраженияв ожидании контекста (контекст может быть выражением, оператором, объявлением, ctor-init-list ...).

А как насчет этого?

int &r = x;

Я уверен, что в этом утверждении преобразования не будет,

, потому что здесь не требуется неявное преобразование .Неявное преобразование применяется только при необходимости.Привязка ссылки не ожидает значения.

, но я запутался, как оператор & вовлечен в это?

Это не так.

0 голосов
/ 13 декабря 2011

«На операнде» должно относиться к x с правой стороны. То есть подвыражение x в выражении int *p = &x; является не значением, а скорее значением l. Сравните это с int a = b;, где подвыражение b равно r-значению (после преобразования).

...