g++ 3.4.5 accepts this code:
template <typename T> struct A
{
static const char* const str;
};
struct B {};
typedef A<B> C;
template<> const char* const C::str = "B";
// Equivalent to following?
// template<> const char* const A<B>::str = "B";
But I'm not sure it's actually legal C++03. In particular,
[14.7p3] In an explicit specialization declaration for a class template, a member of a class template or a class member template, the name of the class that is explicitly specialized shall be a template-id.
Does this requirement say that the non-typedef version must be used at the end of this example? Or have I misinterpreted something?
Edit: Further evidence: Defect Report 403 suggests that it is incorrect to say a type (in that context, the type of an argument of a function call expression) is a template-id because template-id has a syntactic meaning, not a semantic one. Later drafts of the Standard have used "class template specialization" instead of "template-id" in 3.4.2.
This supports the argument that although A<B>
and C
represent the same type (and have identical or nearly identical semantic meaning), A<B>
is a template-id and C
is not, because the term template-id refers to the syntactic content as a sequence of tokens rather than the meaning of those tokens.