Сохраняются ли присвоения результату условных выражений, в которых второй и третий операнды являются переменными одного типа и категории значений?
Узнав о категориях значений, я обнаружил, что следующий фрагмент скомпилирован и работает очень хорошо:
#include <iostream>
int main() {
int x = 1;
int y = 2;
(true ? x : y) = 4;
std::cout << x << std::endl;
}
Вот вывод:
4
Сначала я проверил, было ли это утверждение допустимым в C++, и я считаю, что это из-за следующего:
N4296 5.16.4 Условный оператор [expr.cond]
Если второй и третий операнды являются glvalues одной и той же категории значений и имеют один и тот же тип, результат имеет тип и категорию значений, и это битовое поле, если второй или третий операнд является битовым полем, или если оба являются битовыми полями.
Учитывая, что оба x
а также y
являются lvalue (и, следовательно, glvalues), результатом условного выражения в обоих случаях является lvalue. Исходя из этого, выражение кажется верным. Однако не ясно, должно ли это иметь какой-либо эффект.
Причина, по которой я не уверен, должны ли условные операторы иметь эффект, заключается в том, что тип второго и третьего типов операндов int
, Даже если этот результат int
это lvalue, это не значит, что это должно относиться к x
или же y
, По сути, это может быть фиктивная переменная, которая не даст никакого эффекта, и будет соответствовать стандарту. Другими словами, я не вижу оснований для этого int&
а не отдельный int
,
Мой вопрос...
Это поведение правильно и почему?
Я заранее посмотрел на этот вопрос, но не верю, что он отвечает на мой вопрос. Ответы на этот вопрос относятся к более старому стандарту с другой формулировкой и не отвечают на мой вопрос о том, является ли результат int&
в x
или нет.
1 ответ
Описание условного оператора начинается примерно так. Я цитирую последний рабочий проект, но смысл был одинаковым во всех стандартных версиях, с некоторыми небольшими улучшениями в формулировках с течением времени:
Условные выражения группируются справа налево. Первое выражение контекстуально преобразуется в
bool
(7.3). Оно оценивается, и если оноtrue
, результатом условного выражения является значение второго выражения, в противном случае — значение третьего выражения. Оценивается только одно из второго и третьего выражений. Первое выражение располагается перед вторым или третьим выражением (6.9.1).
Это [expr.cond]/1. Оставшаяся часть [expr.cond] объясняет, как определить тип и категорию значения условного выражения и какие преобразования необходимо применить, если таковые имеются. Эти части не будут повторять тот факт, что результатом является второй или третий операнд, поскольку это уже указано заранее. Итак, когда и второй, и третий операнды являются значениями типаint
, результатом может быть только lvalue, ссылающееся либо на второй, либо на третий операнд, поскольку любой другой результат не будет соответствовать первому абзацу.