Ответ 1
Подтверждена ошибка. Уже исправлено.
Здесь - обсуждение (довольно короткое, чтобы быть честным).
Итак, ответ - нет, void{}
не является законным.
Это была формулировка ошибки рабочего проекта.
Это продолжение этого вопроса.
В комментариях и в ответе сказано несколько раз, что void{}
не является допустимым идентификатором типа или действительным выражением.
Это было прекрасно, это имело смысл, и это было все.
Затем я прошел через [7.1.7.4.1/2] (вычитание типа заполнителя) рабочего проекта.
Там сказано, что:
[...]
- для не отбрасываемого оператораreturn
, который встречается в функции, объявленной с типом возврата, который содержит тип заполнителя,T
- объявленный тип возвращаемого значения, аe
- операнд оператораreturn
. Если операторreturn
не имеет операнда, тоe
естьvoid{}
; [...]
Итак, void{}
(концептуально) законно или нет?
Если это приемлемо, как указано в рабочем проекте (хотя и только как выражение, как если бы оно было), оно должно быть законным. Это означает, что decltype(void{})
также должен быть действительным.
В противном случае, если рабочий проект использует void()
вместо void{}
?
Ну, честно говоря, я совершенно уверен, что я недостаточно квалифицирован, чтобы указать на ошибку в рабочем проекте, поэтому реальный вопрос: что не так в моих рассуждениях?
Что именно void{}
, упомянутое в вышеприведенной марке и почему это юридическое выражение в этом случае?
Подтверждена ошибка. Уже исправлено.
Здесь - обсуждение (довольно короткое, чтобы быть честным).
Итак, ответ - нет, void{}
не является законным.
Это была формулировка ошибки рабочего проекта.
Мне кажется, что кто-то перепутал предыдущий стандарт с новым.
Ранее стандарт сказал следующее: (С++ 14 N4140, 7.1.6.4.7 [dcl.spec.auto]):
Когда оператор [...]
return
встречается в функции объявленный с типом возврата, который содержит тип заполнителя, тип возвращаемого возврата или тип переменной определяется по типу его инициализатора. В случаеreturn
без операнда инициализатор считаетсяvoid()
.
Новый стандарт допускает выражения if constexpr
, поэтому язык должен измениться, чтобы отразить это. if constexpr
приводит к понятию потенциально отброшенного оператора return
(если return
находится в невозбранной ветки constexpr if, то он отбрасывается и тип возврата выводится из других операторов возврата, если они есть).
Возможно, новая формулировка должна выглядеть примерно так:
для не отбрасываемого оператора возврата, который встречается в функции объявленный с типом возврата, который содержит тип заполнителя,
T
- это объявленный тип возвращаемого значения, аe
- операнд оператораreturn
. Если оператор return не имеет операнда, тогдаT
естьauto
, а выводимый тип возврата -void