Что касается преобразования lvalue-rvalue, когда это необходимо?
Я читал довольно много в Интернете, и, похоже, многие люди упомянули следующие правила (но я не мог найти его в стандарте),
Оператор сложения + (и все остальные двоичные операторы) требует, чтобы оба операнда были rvalue, а результат - rvalue.
И так далее.
Я проверил стандарт С++, и он ясно заявляет, что (пункт 3.10/2),
Всякий раз, когда glvalue появляется в контекст, в котором ожидается prvalue, glvalue преобразуется в prvalue
(п. 5/9),
Всякий раз, когда появляется выражение glvalue как операнд оператора, который ожидает значение для этого операнда, lvalue-to-rvalue (4.1), array-to-pointer (4.2) или стандарт функции-to-pointer (4.3) конверсии применяются для преобразования выражение в prvalue.
Он использует термин, который операнд "ожидает" prvalue. Однако, когда я смотрю на оператор добавок, оператор умножения и т.д., Он только упоминает, что результат - это значение 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. Для большинства операторов стандарт ссылается только на результат, но не на требование операнда.
Спасибо.
Btw, я нашел в Стандарте 5.19 относительно постоянного выражения, может очень "неявно" подразумевать, что бинарный оператор требует преобразования lvalue-to-rval в операндах. Для получения более подробной информации, пожалуйста, обратитесь к моему предыдущему вопросу,
смешивание использования constexpr и const?
условное выражение является константой если оно не связано с одним из следующее как потенциально оценивается подвыражение (3.2).
...
- преобразование lvalue-to-rvalue (4.1) если оно не применяется к
---- значение gl интегральный или перечисляемый тип, который относится к энергонезависимому объекту const с предыдущей инициализацией, инициализируется постоянным выражением
Спасибо за чтение.
Ответы
Ответ 1
Таким образом, это, как правило, одна из тех, которые были выведены и неправильно обозначены частями стандарта; Однако в 3.10
[Примечание: некоторые встроенные операторы ожидают lvalue операндов. [Пример: встроенные операторы присваивания ожидают, что их левые операнды будут lvalues. - end example] Другие встроенные операторы дают rvalues, а некоторые ожидают их. [Пример: унарные и двоичные + операторы ожидают аргументы rvalue и дают результаты rvalue. - конец примера] Обсуждение каждого встроенного оператора в разделе 5 указывает, ожидает ли он lvalue-операндов и дает ли оно значение l. - конечная нота]
Обратите внимание на плохо заданный язык "в разделе 5 указывает, ожидает ли он lvalue-операндов и дает ли значение lvalue".
Рассмотрение главы 5 показывает, что каждый случай, когда выражение нуждается или возвращает значение l, перечисляется, однако перечислены очень немногие случаи, относящиеся конкретно к rvalues, я полагаю, что тогда предполагается, что остальные считаются значениями r. >
Я также подозреваю, что это плохо указано, поскольку с точки зрения стандарта это не особенно важно, если преобразование выполняется неявным или явным образом оператором, независимо от того, поведение должно быть последовательным и хорошо себя вести.
Ответ 2
(Прежде всего, извините за мой английский. Исправления абсолютно приветливы)
В стандарте говорится:
§5.7-3 Результатом двоичного + оператора является сумма операндов. [...]
Предположим, что мы имеем выражение e1 + e2
, а выбранный оператор +
является встроенным, выражение хорошо сформировано, e1
и e2
являются арифметическими типами или литьем по арифметическому типу доступно, и все в порядке, прекрасно и идеально!
Таким образом, применяется правило §5.7-3. В другой руке каждый операнд является выражением:
§5-1 [Примечание: [...] Выражение представляет собой последовательность операторов и операндов, которые задают вычисление. Выражение может привести к значению и может вызвать побочные эффекты. - конечная нота]
Он говорит, что выражение может привести к значению из-за выражений void
, таких как выражение delete
или void
, но поскольку мы сказали, что e1 + e2
отлично -defined expression!, мы можем опустить глагол "can", и поэтому мы можем утверждать, что: выражение приводит к значению.
Последняя точка: для арифметических и логических встроенных операторов, я понимаю, хотя она не указана стандартом, имеет значение только значение ее операндов, независимо от их категории значений.
Я думаю, что с выражением достаточно для реализации встроенного оператора +
(и других арифметических операторов), поскольку имеет значение только значение, и значение может быть достигнуто посредством выражения. По этой причине Стандарт не определяет их четко.
Все равно, этот тип вещей очень плохо структурирован. Например, я не нашел места, указывающего, когда оператор получает объект как операнд, а не прямое значение (сомневаюсь, что я в настоящее время пытаюсь решить), если оператор должен непосредственно использовать его значение для вычисления оператора, если значение является результатом оценки объекта и т.д. Очевидно, что важны только ценности, но, что именно говорит, что Стандарт для этих вещей является своего рода загадкой.