Что касается преобразования lvalue в rvalue, когда это требуется? - PullRequest
6 голосов
/ 24 февраля 2011

Я читал довольно много в Интернете, и, похоже, многие упоминали следующие правила (но я не смог найти их в стандарте),

Оператор сложения + (и все другие бинарные операторы) требует, чтобы оба операнда были rvalue, а результат - rvalue. И так далее ..

Я проверил стандарт C ++, и в нем четко указано, что (пункт 3.10 / 2),

Всякий раз, когда в контекст, в котором ожидается prvalue, glvalue преобразуется в prvalue

(пункт 5/9),

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

Используется термин, операнд "ожидает" значения. Однако, когда я смотрю на оператор сложения, оператор умножения и т. Д., В нем только упоминается, что результат является предварительным значением, но ничего не говорится о том, какими «ожидаемыми» будут операнды.

Действительно ли двоичный оператор ожидает, что операнды будут prvalue, имеет значение в следующем случае,

int b = 2;
int a = b + 1;

Если b, как ожидается, будет prvalue, здесь будет преобразование lvalue в rvalue, а затем он выполнит prvalue + prvalue и вернет prvalue, а результат prvalue будет присвоен lvalue a.

Однако, если b не требуется быть prvalue, это будет lvalue + prvalue, а результатом будет prvalue.

Я действительно хочу знать, где в стандарте прямо или косвенно упоминается, что правила для разных операторов? Я проверяю все разделы операторов и только несколько операторов, которые в стандартах прямо упоминают, должны ли операнды и результаты быть lvalue или rvalue. Для большинства операторов в стандарте упоминается только результат, но не требование операнда.

Спасибо.


Кстати, я обнаружил в Стандарте 5.19, что константное выражение может очень и очень «неявно» означать, что двоичный оператор требует преобразования lvalue в rvalue для операндов. Для более подробной информации, пожалуйста, обратитесь к моему предыдущему вопросу,

смешивание использования constexpr и const?

Условное выражение - это константа выражение, если оно не связано с одним из следующее как потенциально вычисленное подвыражение (3.2).

...

- преобразование lvalue в rvalue (4.1) если только он не применяется к

———— целочисленный тип или тип перечисления, относится к энергонезависимому константному объекту с предшествующей инициализацией, инициализируется постоянным выражением

Спасибо за чтение.

Ответы [ 2 ]

4 голосов
/ 24 февраля 2011

Итак, это, как правило, одна из тех предполагаемых и плохо определенных частей стандарта;Однако в 3.10

[Примечание: некоторые встроенные операторы ожидают операнды lvalue.[Пример: все встроенные операторы присваивания ожидают, что их левые операнды будут lvalue.- конец примера] Другие встроенные операторы выдают значения r, а некоторые ожидают их.[Пример: унарные и бинарные операторы + ожидают значения rvalue и дают результаты rvalue.- конец примера] Обсуждение каждого встроенного оператора в разделе 5 указывает, ожидает ли он операндов lvalue и возвращает ли он lvalue.- примечание конца]

Заметьте, что плохо указанный язык "в разделе 5 указывает, ожидает ли он операнды lvalue и дает ли он значение lvalue".

Изучение главы 5 указываетчто каждый случай, когда выражению требуется или возвращается lvalue, перечисляется, однако перечисляются очень немногие случаи, относящиеся конкретно к rvalue, я думаю, что тогда предполагается, что остальные предполагаются как rvalues.

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

1 голос
/ 10 февраля 2014

(Прежде всего, извините за мой английский. Поправки абсолютно приветствуются)

Стандарт гласит:

§5.7-3 Результатом бинарного оператора + являетсясумма операндов.[...]

Предположим, у нас есть выражение e1 + e2, а выбранный оператор + является встроенным, выражение корректно сформировано, e1 и e2 - это арифметические типы или доступно приведение к арифметическому типу, и все в порядке, отлично и прекрасно!

Итак, правило §5.7-3 применимо.С другой стороны, каждый операнд является выражением:

§5-1 [ Примечание : [...] Выражение - это последовательность операторов и операндов, которая определяет вычисление,Выражение может привести к значению и может вызвать побочные эффекты.- конечная нота ]

В нем говорится, что выражение может привести к значению из-за void выражений, таких как выражение delete или void, но так как мы сказали, что e1 + e2 является совершенно определенным выражением !, мы можем опустить глагол «can», и поэтому можем подтвердить, что: выражение приводит к значению .

Последний пункт: для арифметических и логических встроенных операторов я понимаю, что, хотя он и не определен стандартом, имеет значение только значение его операндов, независимо от их категории значения.

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

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

...