When the standard says โno diagnostics are requiredโ, this means that the compiler should not cause an error or warning about incorrect code, but the behavior of the code is still undefined according to the standard, and therefore it won sure to have predictable results. This is intended to simplify the writing of compilers so that they are not required to detect relatively rare or especially unpleasant to detect types of programmer errors.
However, when the rule with "no need for diagnostics" is violated, the compiler is not forbidden to detect the wrong code and cause an error as a courtesy to the user. Thus, in the above example, gcc performs politeness diagnostics for one specific invalid code, and Como performs politeness diagnostics for a similar invalid code. But no diagnostics are required, therefore, in no case does the other compiler violate the standard without generating an error message. Code behavior remains undefined anyway.
A few relevant standard quotes regarding class names and template names:
3.4 / 1
Name search rules are applied uniformly for all names (including typedef-names (7.1.3), namespace-names (7.3) and class names (9.1)), where the grammar allows such names to be discussed in a specific context. A name search associates the use of a name with the declaration (3.1) of that name. A name search should find an unambiguous declaration for the name (see 10.2). [...]
7.1.3 / 3
In a given scope, the typedef specifier should not be used to override the name of any type declared in this scope, for belong to another type. [Example:
class complex { }; typedef int complex;
-end example] Similarly, in a given scope, class or enumeration, you should not declare it with the same name as the name typedef, which is declared in this scope and is of a type other than the class or enumeration itself. [...]
9.1 / 2
A class definition introduces the class name into the area where it defines and hides any class, object, function, or other declaration of that name in the scope (3.3). If a class name is declared in the area where an object, function or enumerator with the same name is also declared, then when both declarations are in the class, the class can only be mentioned using the specified type specifier (3.4.4).
14/5
A class template must not have the same name as any other template, class, function, object, enumeration, enumerator, namespace or type in (3.3), except as specified in (14.5.4). Besides the fact that the function template can be overloaded either (without a template) with the same name or other function templates with the same name (14.8.3), the name of the template declared in the volume namespace or in the class is unique in this area.
14.5.4 / 1
A core class template declaration is one in which the class template name is the identifier. A template declaration, in which the class template name is the template identifier, is a partial specialization of the template class specified in the template identifier. partial specialization of the template class provides an alternative to the definition of a template, which is used instead of the primary definition when the arguments in the specialization correspond to those specified in the partial specialization (14.5.4.1). [...]
So in short:
typedef cannot change the value of an existing typeclass names may conflict with certain types of names, but not with other class namestemplate class names do not include a template parameter and cannot conflict with anything, even with ordinary class names allowed to conflict with- For template specializations, the same identifier template (name) is considered as the corresponding generalized template, but they (obviously) are not the same.
So, there is a conflict in both directions. The name template not allowed to conflict with anything, and typedef not allowed to change A from the type of the template class to a specialization of the type of the template class.