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