Your program is incorrect, and both compilers are right as the standard does not require a diagnostic from a conforming compiler (letting gcc ignore it). A template for which there can be no valid instantiation (specialization in standard jargon) is incorrect even if that template is never instantiated.
In your case, the name B::foo()
inside A<T>::A(int)
is a non-dependent name, so it needs to be resolved during the first phase lookup, and it can only refer to the B
class defined above. Because it is not a static
member function, but a non-static one, the code is incorrect, regardless of the type T
used to instantiate the A<T>
template and the program is ill-formed.
The relevant quote is from 14.6 [temp.res]/8:
Knowing which names are type names allows the syntax of every template definition to be checked. No diagnostic shall be issued for a template definition for which a valid specialization can be generated. If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required.