This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-11-11
[Voted into the WP at the September, 2008 meeting.]
The restrictions on declaring and/or defining classes inside type-specifier-seqs and type-ids are inconsistent throughout the Standard. This is probably due to the fact that nearly all of the sections that deal with them attempt to state the restriction afresh. There are three cases:
7.6.2.8 [expr.new], 8.5 [stmt.select], and 11.4.8.3 [class.conv.fct] prohibit “declarations” of classes and enumerations. That means that
while (struct C* p = 0) ;
is ill-formed unless a prior declaration of C has been seen. These appear to be cases that should have been fixed by issue 379, changing “class declaration” to “class definition,” but were overlooked.
7.5.6 [expr.prim.lambda], 9.1 [dcl.pre], and 9.3.4.6 [dcl.fct] (late-specified return types) do not contain any restriction at all.
All the remaining cases prohibit “type definitions,” apparently referring to classes and enumerations.
Suggested resolution:
Add something like, “A class or enumeration shall not be defined in a type-specifier-seq or in a type-id,” to a single place in the Standard and remove all other mentions of that restriction (allowing declarations via elaborated-type-specifier).
Mike Miller:
An alias-declaration is just a different syntax for a typedef declaration, which allows definitions of a class in the type; I would expect the same to be true of an alias-declaration. I don't have any particularly strong attachment to allowing a class definition in an alias-declaration. My only concern is introducing an irregularity into what are currently exact-match semantics with typedefs.
There's a parallel restriction in many (but not all?) of these places on typedef declarations.
Jens Maurer:
Those are redundant, as typedef is not a type-specifier, and should be removed as well.
Proposed resolution (March, 2008):
Delete the indicated words from 7.6.1.7 [expr.dynamic.cast] paragraph 1:
...Types shall not be defined in a dynamic_cast....
Delete the indicated words from 7.6.1.8 [expr.typeid] paragraph 4:
...Types shall not be defined in the type-id....
Delete the indicated words from 7.6.1.9 [expr.static.cast] paragraph 1:
...Types shall not be defined in a static_cast....
Delete the indicated words from 7.6.1.10 [expr.reinterpret.cast] paragraph 1:
...Types shall not be defined in a reinterpret_cast....
Delete the indicated words from 7.6.1.11 [expr.const.cast] paragraph 1:
...Types shall not be defined in a const_cast....
Delete paragraph 5 of 7.6.2.5 [expr.sizeof]:
Types shall not be defined in a sizeof expression.
Delete paragraph 5 of 7.6.2.8 [expr.new]:
The type-specifier-seq shall not contain class declarations, or enumeration declarations.
Delete paragraph 4 of 7.6.2.6 [expr.alignof]:
A type shall not be defined in an alignof expression.
Delete paragraph 3 of 7.6.3 [expr.cast]:
Types shall not be defined in casts.
Delete the indicated words from 8.5 [stmt.select] paragraph 2:
...The type-specifier-seq shall not contain typedef and shall not declare a new class or enumeration....
Add the indicated words to 9.2.9 [dcl.type] paragraph 3:
At least one type-specifier that is not a cv-qualifier is required in a declaration unless it declares a constructor, destructor or conversion function. [Footnote: ... ] A type-specifier-seq shall not define a class or enumeration unless it appears in the type-id of an alias-declaration (9.2.4 [dcl.typedef]).
Delete the indicated words from 11.4.8.3 [class.conv.fct] paragraph 1:
...Classes, enumerations, and typedef-names shall not be declared in the type-specifier-seq....
Delete the indicated words from 14.4 [except.handle] paragraph 1:
...Types shall not be defined in an exception-declaration.
Delete paragraph 6 of 14.5 [except.spec]:
Types shall not be defined in exception-specifications.
[Drafting note: no changes are required to 7.5.6 [expr.prim.lambda], 9.2.4 [dcl.typedef], 9.12.2 [dcl.align], 9.7.1 [dcl.enum], 9.3.4.6 [dcl.fct], 13.2 [temp.param], or 13.3 [temp.names].]