Подтвердить что ты не робот

Является ли void {} законным или нет?

Это продолжение этого вопроса.
В комментариях и в ответе сказано несколько раз, что void{} не является допустимым идентификатором типа или действительным выражением.

Это было прекрасно, это имело смысл, и это было все.

Затем я прошел через [7.1.7.4.1/2] (вычитание типа заполнителя) рабочего проекта.
Там сказано, что:

[...]
- для не отбрасываемого оператора return, который встречается в функции, объявленной с типом возврата, который содержит тип заполнителя, T - объявленный тип возвращаемого значения, а e - операнд оператора return. Если оператор return не имеет операнда, то e есть void{}; [...]

Итак, void{} (концептуально) законно или нет?
Если это приемлемо, как указано в рабочем проекте (хотя и только как выражение, как если бы оно было), оно должно быть законным. Это означает, что decltype(void{}) также должен быть действительным. В противном случае, если рабочий проект использует void() вместо void{}?


Ну, честно говоря, я совершенно уверен, что я недостаточно квалифицирован, чтобы указать на ошибку в рабочем проекте, поэтому реальный вопрос: что не так в моих рассуждениях?
Что именно void{}, упомянутое в вышеприведенной марке и почему это юридическое выражение в этом случае?

4b9b3361

Ответ 1

Подтверждена ошибка. Уже исправлено.
Здесь - обсуждение (довольно короткое, чтобы быть честным).

Итак, ответ - нет, void{} не является законным.
Это была формулировка ошибки рабочего проекта.

Ответ 2

Мне кажется, что кто-то перепутал предыдущий стандарт с новым.

Ранее стандарт сказал следующее: (С++ 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