This is an academic question.
In the report for GCC bug 38764, there are the following examples:
template < class T > struct A {};
typedef A< float > A; // Accepted by Comeau, but not GCC
typedef ::A< float > A; // Accepted by GCC but not Comeau
I see why the code may be invalid, but I have trouble with one of the comments:
This code is invalid but the standard says for this case no diagnostic is required so both compilers are correct according to the standard.
Why is the code that is “invalid” accepted by the standard as valid? What does the standard say about this case in particular (template + type with the same name) and, in general, about namespaces for various entities (types, templates, functions, variables)?
When the standard says “no diagnostic required”, that means that the compiler does not have to produce an error or warning about the invalid code, but that the code’s behavior is still undefined according to the standard and so it won’t necessarily have predictable results. This is intended to make things easier on compiler-writers so that they are not obligated to detect relatively rare or particularly troublesome-to-detect sorts of programmer errors.
However, when a rule with “no diagnostic required” is violated, the compiler is not prohibited from detecting the invalid code and producing an error as a courtesy to the user. So in the example given, gcc is producing a courtesy diagnostic for one particular sort of invalid code, and Comeau is producing a courtesy diagnostic for a similar sort of invalid code. But neither diagnostic is required, so in neither case is the other compiler in violation of the standard by not producing an error message. The behavior of the code remains undefined in any case.
Several relevant standards quotations regarding class names and template names:
3.4/1
7.1.3/3
9.1/2
14/5
14.5.4/1
So, in summary:
typedefs cannot change the meaning of an existing typeclassnames can conflict with certain sorts of names, but not other class namestemplateclass names do not include the template parameter, and cannot conflict with anything, even things that normal class names are allowed to conflict withSo there’s a conflict in both directions here. The
templatename is not allowed to conflict with anything, and thetypedefis not allowed to changeAfrom a template class type to a specialization of a template class type.