Произойдет ли преобразование lvalue в rvalue?

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

Например:

int x;
int *p = &x;

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

Редактировать:

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

int &r = x;

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

5 ответов

Решение

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

Это отличается от, скажем, одинарного + оператор. Если ты пишешь +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.

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

Стандартная цитата в основном говорит операнд, на котором & применяется, не становится значением. Это остается lvalue.

На самом деле, операнд & не может быть Это должно быть 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 это значение. То есть выражение &x является значением r и не может появляться справа от оператора присваивания:

&r = whatever; //illegal

Я надеюсь, что это поможет вам понять цитату.


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

int &r = x;

Это нормально. Вот & марки r ссылка на объект x, & здесь не оператор и не связан со ссылкой r скорее это связано с типом. Это менее запутанно, чтобы написать это как:

int&  r = x;

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

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

Стандарт C++ (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" (как раз наоборот), поэтому неявное преобразование lvalue в rvalue не является необходимым и не будет применяться.

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

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

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

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

int &r = x;

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

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

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

Это не.

Другие вопросы по тегам