Suppose there is a code like this:
template <typename T>
CLASS_KEY1 X{};
PREFIX template CLASS_KEY2 X<int>;
where CLASS_KEY1
, CLASS_KEY2
and PREFIX
are macros. CLASS_KEY1
and CLASS_KEY2
may be expanded to class
, struct
or union
keywords. PREFIX
may be expanded to empty set of characters or extern
keyword.
Here is the table which shows when such code compiles (Yes
- compiles, No
- does not compile) for all combinations of macros values (compiler gcc-4.8.1, option -std=c++11
):
PREFIX extern extern extern
CLASS_KEY1\CLASS_KEY2 class struct union class struct union
class Yes Yes? No Yes Yes? No
struct Yes? Yes No Yes? Yes No
union No No Yes No No Yes
Is it a bug in gcc or standard requirement (strange cases are labeled with question marks)? What about other compilers?
Section 7.1.6.3 (Elaborated type specifiers) of the C++11 standard says :
The class-key or
enum
keyword present in the elaborated-type-specifier shall agree in kind with the declaration to which the name in the elaborated-type-specifier refers. This rule also applies to the form of elaborated-type-specifier that declares a class-name orfriend
class since it can be construed as referring to the definition of the class. Thus, in any elaborated-type-specifier, theenum
keyword shall be used to refer to an enumeration (7.2), theunion
class-key shall be used to refer to aunion
(Clause 9), and either theclass
orstruct
class-key shall be used to refer to aclass
(Clause 9) declared using theclass
orstruct
class-key.
So, the behavior you're seeing is allowed.