<!-- saved from url=(0022)http://internet.e-mail -->
<HTML>
<HEAD>
   <style>
     <!--
       P.indented {margin-left: 4em}
       XMP.indented {margin-left: 4em}
     -->
   </style>
   <TITLE>
       Definition of Dependent Name - Revision 2
   </TITLE>
</HEAD>

<BODY>

<TABLE ALIGN=RIGHT CELLSPACING=0 CELLPADDING=0 >
<TR>
<TD ALIGN=RIGHT>Document number:</TD>

<TD>&nbsp;00-0056/N1279</TD>
</TR>

<TR>
<TD ALIGN=RIGHT>Date:</TD>

<TD>&nbsp;November 1, 2000</TD>
</TR>

<TR>
<TD ALIGN=RIGHT>Author:</TD>

<TD>&nbsp;John Spicer, Edison Design Group</TD>
</TR>

<TR>
<TD></TD>

<TD>&nbsp;<TT>jhs@edg.com</TT></TD>
</TR>
</TABLE>

<BR CLEAR=ALL>

<CENTER>
<H2>
Definition of Dependent Name - Revision 2
</H2>
</center>

<h3>Introduction</h3>
<p>
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.
<p>
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.
<p>
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.

<h3>Proposed Changes</h3>
<p>
<h4>
Replace section 14.6.2.1 (_temp.dep.type_) with the following:
</h4>

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 <em>current instantiation</em> if it is
<ul>
<li>
the injected-class-name (_class_) of the class template, or nested class,
<li>
in the definition of a primary class template, the name of the class
template followed by the template argument list of the primary template
(as described below) enclosed in &lt;>,
<li>
in the definition of a nested class of a class template, the name
of the nested class referenced as a member of the current instantiation, or
<li>
in the definition of a partial specialization, the name of the class
template followed by the template argument list of the partial
specialization enclosed in &lt;>.
</ul>
<p>
The template argument list of a primary template is a template argument
list in which the n<sup>th</sup> template argument has the value of the
n<sup>th</sup> template parameter of the class template.
<p>
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.
<p>
[<em>Example:</em>
<xmp class=indented>
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
};
</xmp>
<em>--end example</em>]

<p>
A name is a <em>member of the current instantiation</em> if it is
<ul>
<li>
An unqualified name that, when looked up, refers to a member of a class
template.
[<em>Note:</em> This can only occur when looking up a name in a scope enclosed
by the definition of a class template.]
<li>
A <em>qualified-id</em> in which the <em>nested-name-specifier</em>
refers to the current instantiation.
</ul>
[<em>Example:</em>
<xmp class=indented>
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
}

</xmp>
<em>--end example</em>]
<p>
A name is a <em>member of an unknown specialization</em> if the name
is a <em>qualified-id</em> in which the <em>nested-name-specifier</em>
names a dependent type that is not the current instantiation.
<p>
A type is dependent if it is
<ul>
<li>
a template parameter,
<li>
a member of an unknown specialization,
<li>
a nested class that is a member of the current instantiation,
<li>
a cv-qualified type where the cv-unqualified type is
dependent,
<li>
a compound type constructed from any dependent type,
<li>
an array type constructed from any dependent type or whose size is
specified by a constant expression that is value-dependent, or
<li>
a <em>template-id</em> in which either the template name is a template
parameter or any of the template arguments is a dependent type or an
expression that is type-dependent or value-dependent.
</ul>

<em>[Note:</em> 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.<em>]</em>

<xmp class=indented>
</xmp>

<h4>In 14.6.2.2:</h4>

<p>
Replace
<ul>
<li>
a <em>nested-name-specifier</em> that contains a <em>class-name</em> that
names a dependent type.
</ul>
<p>
with
<ul>
<li>a <em>nested-name-specifier</em> or <em>qualified-id</em> that names
a member of an unknown specialization
</ul>

<p>
Add the following paragraph:
<ul>
A class member access expression (_expr.ref_) is type-dependent
if the type of the referenced member is dependent.
<em>[Note:</em> In an expression of the form <code>x.y</code> or
<code>xp->y</code> the type of the expression is usually the type of
the member <code>y</code> of class of <code>x</code> (or the class
pointed to by <code>xp</code>).  However, if <code>x</code> or
<code>xp</code> refers to a dependent type that is not the current
instantiation, the type of <code>y</code> is always dependent.  If
<code>x</code> or <code>xp</code> refers to a non-dependent type or
refers to the current instantiation, the type of <code>y</code> is the
type of the class member access expression.<em>]</em>
</ul>

<h4>In 14.6 paragraph 3:</h4>

<p>
Replace

<ul>
A <em>qualified-name</em> that refers to a type and that depends on
a <em>template-parameter</em> (_temp.dep_) shall be prefixed by
the keyword <tt>typename</tt>.
</ul>

<p>
with

<ul>
A <em>qualified-name</em> that refers to a type and that depends on
a <em>template-parameter</em> (_temp.dep_) but does not refer to a
member of the current instantiation shall be prefixed by
the keyword <tt>typename</tt>.
</ul>

<h4>In 14.2 paragraph 4:</h4>

<p>
Replace

<ul>
When the name of a member template specialization appears after
<tt>.</tt> or <tt>-></tt> in a <em>postfix-expression</em>, or after
<em>nested-name-specifier</em> in a <em>qualified-id</em>, and the
<em>postfix-expression</em> or <em>qualified-id</em> explicitly
depends on a <em>template-parameter</em> (_temp.dep_), the member
template name must be prefixed by the keyword
<tt>template</tt>. Otherwise the name is assumed to name a
non-template.
</ul>

<p>
with

<ul>
When the name of a member template specialization appears after
<tt>.</tt> or <tt>-></tt> in a <em>postfix-expression</em>, or after
<em>nested-name-specifier</em> in a <em>qualified-id</em>, and the
<em>postfix-expression</em> or <em>qualified-id</em> explicitly
depends on a <em>template-parameter</em> (_temp.dep_) but does not
refer to a member of the current instantiation (_temp_dep_type_), the member
template name must be prefixed by the keyword
<tt>template</tt>. Otherwise the name is assumed to name a
non-template.
</ul>

<h4>In 14.6.1 paragraph 2:</h4>

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

<ul>
Within the scope of a class template, when the unqualified name of a
nested class of the class template is referred to, it is
equivalent to the name of the nested class qualified by the name
of the enclosing class template.
<em>[Example:</em>
<xmp class=indented>
template <class T> struct A {
	class B {};
	// B is equivalent to A::B, which is equivalent to A<T>::B,
	// which is dependent.
	class C : B { };
};
</xmp>
<em>--end example]</em>
</ul>


<h3>End of document.</h3>

</body>














