CWG Issue 224 (original) (raw)

In the definition of a class template, a nested class of a class template, a member of a class template, or a member of a nested class of a class template, a name refers to the current instantiation if it is

The template argument list of a primary template is a template argument list in which the nth template argument has the value of the nth template parameter of the class template.

A template argument that is equivalent to a template parameter (i.e., has the same constant value or the same type as the template parameter) can be used in place of that template parameter in a reference to the current instantiation. In the case of a nontype template argument, the argument must have been given the value of the template parameter and not an expression involving the template parameter.

[Example:

template class A { A* p1; // A is the current instantiation A* p2; // A is the current instantiation A<T*> p3; // A<T*> is not the current instantiation ::A* p4; // ::A is the current instantiation class B { B* p1; // B is the current instantiation A::B* p2; // A::B is the current instantiation typename A<T*>::B* p3; // A<T*>::B is not the // current instantiation }; };

template class A<T*> { A<T*>* p1; // A<T*> is the current instantiation A* p2; // A is not the current instantiation };

template <class T1, class T2, int I> struct B { B<T1, T2, I>* b1; // refers to the current instantiation B<T2, T1, I>* b2; // not the current instantiation typedef T1 my_T1; static const int my_I = I; static const int my_I2 = I+0; static const int my_I3 = my_I; B<my_T1, T2, my_I>* b3; // refers to the current instantiation B<my_T1, T2, my_I2>* b4; // not the current instantiation B<my_T1, T2, my_I3>* b5; // refers to the current instantiation };

—_end example_]

A name is a member of the current instantiation if it is

[Example:

template class A { static const int i = 5; int n1[i]; // i refers to a member of the current instantiation int n2[A::i]; // A::i refers to a member of the current instantiation int n3[A::i]; // A::i refers to a member of the current instantiation int f(); };

template int A::f() { return i; // i refers to a member of the current instantiation }

—_end example_]

A name is a member of an unknown specialization if the name is a qualified-id in which the_nested-name-specifier_ names a dependent type that is not the current instantiation.

A type is dependent if it is

[Note: Because typedefs to not introduce new types, but instead simply refer to other types, a name that refers to a typedef that is a member of the current instantiation is dependent only if the type referred to is dependent.]