1. Replace T with the type used with this template.
From what I understand the problem is that at the time of parsing of the template, T is not known. The compiler cannot replace T with any type since the template has not been instantiated.
I am not sure if this is a correct counterexample, but suppose there is a specialisation of std::list such that, for that particular A<T>, const_iterator is a member variable, not a type. Now, If T happens to be any other type, const_iterator would be a typename. But if T is of that type such that A<T> has this unusual specialisation, const_iterator would be a member variable.
This would not happen in practice since we are dealing with a standard container (and my knowledge of templates and C++ in general is such that I am not sure if it is even legal/possible), so perhaps Stephen Dewhurst's example from C++ Common Knowledge Item #49 is clearer:
Consider the following fragment:
Code:
template <typename T>
void aFuncTemplate( T &arg ) {
...T::ElemT...
When the compiler encounters the qualified name T::ElemT, what does it know? From the template parameter list it knows that T is a type name of some sort. It can also determine that T is a class name because we've employed the scope operator (: to access a nested name of T. But that's all the compiler knows, because there is no information available about the content of T. For instance, we could call aFuncTemplate with a PtrList, in which case T::ElemT would be a type name.
Code:
PtrList<State> states;
//...
aFuncTemplate( states ); // T::ElemT is PtrList<State>::ElemT
But what if we were to instantiate aFuncTemplate with a different type?
Code:
struct X {
enum Types { typeA, typeB, typeC } ElemT;
//...
};
X anX;
//...aFuncTemplate( anX ); // T::ElemT is X::ElemT
In this case, T::ElemT is the name of a data member - a nontype name. What's a compiler to do? The standard tossed a coin, and in cases where it can't determine the type of a nested name, the compiler will assume the nested name is a nontype name.
NB:
For your reference, Dewhurst's PtrList example is:
Code:
template <typename T>
class PtrList {
public:
//...
typedef T *ElemT;
void insert( ElemT );
//...
};