Document number:  00-0056/N1279
Date:  November 1, 2000
Author:  John Spicer, Edison Design Group
 jhs@edg.com

Definition of Dependent Name - Revision 2

Introduction

This document contains the proposed working paper changes for the definition of dependent name. (See core issue #224). This is a revision of N1251. This issue was described in detail in N1231.

At the Tokyo meeting, the core group agreed on the direction proposed in N1231, that the "dependency" of a name should be based on its type, and not on the form of reference used, and that special rules are needed to get the desired behavior when referring to names declared within the class template itself.

N1251 proposed specific working paper changes. These changes were reviewed in Toronto. In addition, several drafts of this document were also reviewed in Toronto. This document incorporates the changes resulting from those reviews.

Proposed Changes

Replace section 14.6.2.1 (_temp.dep.type_) with the following:

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 T> class A { A* p1; // A is the current instantiation A<T>* p2; // A<T> is the current instantiation A<T*> p3; // A<T*> is not the current instantiation ::A<T>* p4; // ::A<T> is the current instantiation class B { B* p1; // B is the current instantiation A<T>::B* p2; // A<T>::B is the current instantiation typename A<T*>::B* p3; // A<T*>::B is not the // current instantiation }; }; template <class T> class A<T*> { A<T*>* p1; // A<T*> is the current instantiation A<T>* p2; // A<T> 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 T> 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<T>::i]; // A<T>::i refers to a member of the current instantiation int f(); }; template <class T> int A<T>::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 do 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.]

In 14.6.2.2:

Replace

with

Add the following paragraph:

In 14.6 paragraph 3:

Replace

with

In 14.2 paragraph 4:

Replace

with

In 14.6.1 paragraph 2:

Remove the following text, which was added for issue 108. The updated definition of dependent name now addresses this case.

End of document.