В C ++ 11 спецификатор типа включает в себя спецификаторы класса а также перечислители. (иначе определения классов и перечисления)
В соответствии с грамматикой / синтаксисом — спецификаторы типа могут появляться в нескольких местах языка, но не во всех этих местах разрешены спецификаторы класса и перечисления enum.
Например:
struct C{} c;
// ok: types may be defined in the specifiers of a simple declaration
void f(struct S{});
// error: types may not be defined in parameter types
constexpr auto i = sizeof(enum E{});
// error: types may not be defined in ‘sizeof’ expressions
Где в стандарте разделены эти виды использования спецификаторов типов на те, где типы могут и не могут быть определены? Например, где находится правило, которое говорит, что типы не могут быть определены в выражении sizeof?
Причина, по которой его нельзя найти в стандарте C ++, заключается в том, что он фактически запрещен в дельте из стандарта C.
В C.1.4 у нас есть следующее: Change: Types must be declared in declarations, not in expressions In C, a sizeof expression or cast expression may create a new type.
который показывает запрет в вопросе.
Это явно вызвано в 7.1.6 / 3:
По крайней мере, один спецификатор типа, который не является квалификатором cv, требуется в
объявление, если оно не объявляет конструктор, деструктор или
функция преобразования.92 Спецификатор типа-seq не должен определять класс
или перечисление, если оно не появляется в идентификаторе типа
декларация псевдонима (7.1.3), которая не является декларацией
Шаблон-декларации.
где часть особого интереса заключается в том, что A type-specifier-seq shall not define a class or enumeration unless...
От N3797:
8.3.5 / 9 Типы не должны быть определены в возвращаемых типах или параметрах. Тип параметра или тип возвращаемого значения для определения функции должен
не быть неполным типом класса (возможно, cv-квалифицированным), если только
функция удалена (
8.4.3) или определение вложено в спецификацию члена для этого класса (включая определения во вложенных классах, определенных в
класс).
Это блокирует определение новых типов в объявлении функции.
Следующие два являются другими угловыми случаями, не упомянутыми ФП:
11.3 / 2 Класс не должен быть определен в объявлении друга.
14.1 / 2 Типы не должны быть определены в декларации параметра шаблона.
Наконец, этот пункт блокирует его в sizeof
и в других местах:
7.1.6 / 3 Спецификатор типа-seq не должен определять класс или перечисление, если он не указан в идентификаторе типа
декларация alias (7.1.3), которая не является декларацией шаблона
Обратите внимание, что C не имеет этого ограничения (C.1.4)
Кроме того, в предыдущей версии стандарта C ++ у нас было:
5.3.3p5 Типы не должны быть определены в выражении sizeof
который я не могу найти в самой последней версии стандартных предложений, и он избыточен под N3797 как sizeof
Путь для определения типа в грамматике через type-specifier-seq
и заблокировано 7.1.6 / 3:
sizeof(type-id)
-> type-id
-> type-specifer-seq
-> type-specifier
-> class-specifier