Инициализация ссылочных переменных с помощью условного оператора - PullRequest
7 голосов
/ 08 февраля 2012

Следующий код C ++ недопустим, поскольку ссылочные переменные требуют инициализаторов:

int& a; // illegal
if (isfive) {
  a = 5;
} else {
  a = 4;
}

Однако MSVC, похоже, считает, что все в порядке:

int& a = isfive ? 5 : 4;

Это означает, что MSVC фактически обрабатывает условный оператор как отдельное выражение, а не расширяет его в оператор if-else.

Всегда ли C ++ правильно инициализировать ссылку, используя условный оператор?

Ответы [ 6 ]

8 голосов
/ 08 февраля 2012

Тернарный оператор не расширяется до конструкции if-else (не в зависимости от языка, реализация может генерировать эквивалентные двоичные файлы, но на уровне языка они различаются).Таким образом, следующий код действителен:

int four = 4, five = 5;
int& r = condition? four : five;

Исходный пример в вопросе зависит от расширения Microsoft, которое (неправильно) позволяет связать неконстантную ссылку с выражением rvalue.

5 голосов
/ 08 февраля 2012

MSVC имеет нестандартное «расширение». Это означает, что он допускает неработающий код. Есть веская причина, по которой это запрещено.

Обратите внимание, что

int& a = 5;

также не разрешено в стандарте C ++.

В общем случае допустимо инициализировать ссылку const любым выражением, которое может быть преобразовано в правильный тип (включая использование условного оператора). И допустимо инициализировать не const ссылку с lvalue правильного типа, который условный оператор выдает при определенных условиях.

3 голосов
/ 08 февраля 2012

Код, который вы опубликовали, не компилируется с VC ++ 2010:

Ошибка 1, ошибка C2440: «инициализация»: невозможно преобразовать из «int» в «int &»

Изменение строки на:

const int& a = isfive ? 5 : 4; 

делает компиляцию.

3 голосов
/ 08 февраля 2012

Условный оператор - это выражение, а не оператор.Вполне нормально инициализировать такую ​​ссылку.Это немного похоже на инициализацию ссылки путем вызова функции.

Обратите внимание, что ваша ссылка должна быть const, если вы привязываете ее к временным файлам (правило, которое MSVC ++ тупо игнорирует).

1 голос
/ 08 февраля 2012

это не нормально

int& a = isfive ? 5 : 4;

, если вы не объявите ссылку "a" как const.

0 голосов
/ 08 февраля 2012

Это оператор, часть выражения, а не оператор.И вы не можете оставить ссылку неинициализированной даже на короткое время; -)

...