Произойдет ли преобразование 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;
Я уверен, что не будет никакого преобразования в этом утверждении,
потому что здесь не требуется неявное преобразование. Неявное преобразование применяется только при необходимости. Ссылочная привязка не ожидает значения.
но я запутался, как & оператор участвует в этом?
Это не.