С++ 11 стандартное ref для разрешенных типов определений в спецификаторе типов?
В С++ 11 спецификатор типа включает спецификаторы классов и спецификаторы перечисления. (так называемые определения классов и определения перечислений)
В соответствии с спецификаторами типа грамматика/синтаксис могут отображаться в нескольких местах на языке, но не во всех этих местах допускаются спецификаторы спецификаций и спецификаторов перечисления.
Например:
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?
Ответы
Ответ 1
Причина, по которой он не может быть найден в стандарте С++, заключается в том, что он фактически запрещен в дельтах из стандарта 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 не должен определять класс или перечисление, если оно не отображается в идентификаторе типа alias-declaration (7.1.3), которая не является объявлением Шаблон-декларации.
где часть особого интереса состоит в том, что A type-specifier-seq shall not define a class or enumeration unless...
Ответ 2
Из N3797:
8.3.5/9 Типы не должны определяться в обратном или параметрическом типах. Тип параметра или возвращаемый тип для определения функции должен не быть неполным классом (возможно, с квалификацией cv), если только функция удаляется ( 8.4.3), или определение вложено в спецификацию участника для этого класса (включая определения в вложенных классах, определенных в класс).
Это блокирует определение новых типов в объявлении функции.
Следующие два являются другими угловыми случаями, не упомянутыми OP:
11.3/2 Класс не должен определяться в объявлении друга.
14.1/2 Типы не должны определяться в объявлении параметра шаблона.
Наконец, это предложение блокирует его в sizeof
и в другом месте:
7.1.6/3 Тип-спецификатор-seq не должен определять класс или перечисление, если он не отображается в идентификаторе типа alias-declaration (7.1.3), которая не является объявлением объявления шаблона
Обратите внимание, что C не имеет этого ограничения (C.1.4)
Кроме того, в предыдущей версии стандарта С++ мы имели:
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