Why are typedef templates illegal?
From a practical point of view, I understand that both typedef
and test
are somewhat "superfluous" and need to be removed if we want the following code to compile:
template< typename type_t >
typedef struct tagTest
{
int a;
} test;
However, I thought that the set of typedef declarations was a subset of the set of declarations. They just happened to have that specific decl-specifier. That was my rationalization for
typedef struct tagTest
{
int a;
} test;
introducing the identifier test
and declaring the structure tagTest
. If that interpretation is correct, then the following paragraph from the standard should allow template
typedef
's (although not with the meaning given by the keyword using
).
The declaration in a template-declaration shall — (1.1) declare or define a function, a class, or a variable, or — (1.2) define a member function, a member class, a member enumeration, or a static data member of a class template or of a class nested within a class template, or — (1.3) define a member template of a class or class template, or — (1.4) be an alias-declaration.
I cannot see error in my reasoning, yet the conclusion is illegal.
What are the relevant parts of the standard that solve the above conundrum?
UPDATE Part of the above reasoning uses the fact that typedef
struct
declares a structure. The typedef
specifier, as far as I understand it, implies that any variables declared are really types. That is, the typedef
upgrades test
from a mere variable to a type that is equivalent to the declared tagTest
. That is why the following code compiles (albeit with a warning).
typedef struct tagTest
{
int a;
};
tagTest t;
One of the answers takes care of the superfluous test
. But, it is possible to use typedef without a declarator because "Init-declarator-list is optional when declaring a named class/struct/union or a named enumeration"
Template typedefs weren't allowed pre-C++11 and with C++11 template aliases were introduced to address those issues. Cfr. C++ template typedefs and wikipedia.
Since, as you noted, the standard doesn't allow typedef
to be in there, the code is invalid
alias-declaration:
using identifier attribute-specifier-seqopt= type-id ;
typedef
declarations are not alias declarations.
Furthermore you can't have a declarator if you're declaring a class template, it is explicitly forbidden by the standard
[temp]/p3
In a template-declaration, explicit specialization, or explicit instantiation the init-declarator-list in the declaration shall contain at most one declarator. When such a declaration is used to declare a class template, no declarator is permitted .
so not even the following will compile
template< typename type_t >
struct tagTest
{
int a;
} test;
Edit:
It is nowhere specified that
typedef struct S { };
should be an error, thus both gcc and clang accept it with a warning. I assume Clang counts on [temp]/3 to issue an error in case typedef was being used with a template while gcc rejects this code immediately
template<typename T>
typedef struct S { };
cfr. clang bug 22249
C does not support templates and the
typedef struct tagX {
} X;
syntax in C++ is vestigial C, there to allow continued support for C headers etc, not for use in actual C++.
The C++ syntax for the above is
struct X {};
(YMMV on brace placement)
Independently from what the typedef
defines, that is a typedef
declaration, which is not listed in those cases:
And just to be clear typedef
declarations are not alias declarations. Alias declaration, as specified by the grammar at §7 of the standard are:
alias-declaration:
using identifier attribute-specifier-seqopt= type-id ;
Not to mention that if this was possible, then template using
declaration would not be nearly as "cool" as they are today, and there would be little to no sense to have both.
上一篇: 一般用于矢量的typedef可以吗?
下一篇: 为什么typedef模板是非法的?