<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<style>
.ins {background-color:#A0FFA0;font-weight: bold}
.del {background-color:#FFA0A0;text-decoration:line-through}
</style>
<title>Dependent Bases and the Current Instantiation: Wording for Core Issue 1043</title>
<body>

Author: Doug Gregor &lt;doug.gregor@gmail.com&gt;<br>
Document number: N3283=11-0053<br>
Date: 2011-03-24<br>

<h1>Dependent Bases and the Current Instantiation: Wording for Core Issue 1043</h1>

<p><b>Proposed resolution</b>: </p>

<p>Modify 14.2 [temp.names] paragraph 4 as follows:</p>

<ol start="4">
  <li>When the name of a member template specialization appears after <code>.</code> or <code>-&gt;</code> in a <var>postfix-expression</var> or after a <var>nested-name-specifier</var> in a <var>qualified-id</var>, and the object expression of the <var>postfix-expression</var> <span class="ins">is type-dependent</span> or the <var>nested-name-specifier</var> in the <var>qualified-id</var> <span class="del">depends on a template parameter (14.6.2 [temp.dep])</span><span class="ins">refers to a dependent type,</span> but <span class="ins">the name is not</span> <span class="del">does not refer to</span> a member of the current instantiation (14.6.2.1 [temp.dep.type]), the member template name must be prefixed by the keyword <code>template</code>. Otherwise the name is assumed to name a non-template.</li>
</ol>

<p>Modify 14.6 [temp.res] paragraph 3 as follows:</p>

<ol start="3">
  <li>When a <var>qualified-id</var> is intended to refer to a type that is not a member of the current instantiation (14.6.2.1 [temp.dep.type]) and its <var>nested-name-specifier</var> <span class="del">depends on a template-parameter (14.6.2 [temp.dep])</span><span class="ins">refers to a dependent type</span>, it shall be prefixed by the keyword <code>typename</code>, forming a <var>typename-specifier</var>. If the <var>qualified-id</var> in a <var>typename-specifier</var> does not denote a type, the program is ill-formed.</li>
</ol>

<p>Modify 14.6 [temp.res] paragraphs 6 and 7 as follows:</p>

<ol start="6">
  <li>If, for a given set of template arguments, a specialization of a template is instantiated that refers to a <var>qualified-id</var> that denotes a type, and the <span class="del"><var>nested-name-specifier</var> of the <var>qualified-id</var> depends on a template parameter</span><span class="ins"><var>qualified-id</var> refers to a member of an unknown specialization</span>, the <var>qualified-id</var> shall either be prefixed by <code>typename</code> or shall be used in a context in which it implicitly names a type as described above.</li>

  <li>Within the definition of a class template or within the definition of a member of a class template <span class="ins">following the <var>declarator-id</var></span>, the keyword <code>typename</code> is not required when referring to the <span class="del">unqualified</span> name of a previously declared member of the class template that declares a type. <span class="ins">[<i>Note</i>: such names can be found using unqualified name lookup (3.4.1 [basic.lookup.unqual]), class member lookup (3.4.3.1 [class.qual]) into the current instantiation (14.6.2.1 [temp.dep.type]), or class member access expression lookup (3.4.5 [basic.lookup.classref]) when the type of the object expression is the current instantiation (14.6.2.2 [temp.dep.expr]). - <i>end note</i>]</span></li>
</ol>

<p>Modify 14.6.2.1 [temp.dep.type] paragraphs 4 and 5 as follows:</p>

<OL start="4">

<li>A name is a <i>member of the current instantiation</i> if it is
<ul>
  <li>An unqualified name that, when looked up, refers to a<span class="ins">t least one</span> member of <span class="del">a class template</span> <span class="ins">the current instantiation or a non-dependent base class thereof</span>. [<i>Note</i>: this can only occur when looking up a name in a scope enclosed by the definition of a class template. - <i>end note</i> ]</li>

  <li>A <var>qualified-id</var> in which the <var>nested-name-specifier</var> refers to the current instantiation<span class="ins"> and that, when looked up, refers to at least one member of the current instantiation or a non-dependent base class thereof. [<i>Note</i>: if no such member is found, and the current instantiation has any dependent base classes, then the <var>qualified-id</var> is a member of an unknown specialization; see below. - <i>end note</i>]</span>
  </li>
  
  <li><span class="ins">An <var>id-expression</var> denoting the member in a class member access expression (5.2.5 [expr.ref]) for which the type of the object expression is the current instantiation, and the <var>id-expression</var>, when looked up (3.4.5 [basic.lookup.classref]), refers to at least one member of the current instantiation or a non-dependent base class thereof. [<i>Note</i>: if no such member is found, and the current instantiation has any dependent base classes, then the <var>id-expression</var> is a member of an unknown specialization; see below. - <i>end note</i>]</span></li>

</ul>
</li>

<li>A name is a <i>member of an unknown specialization</i> if <span class="ins">it is</span>
<ul>
  <li><span class="del">the name is a</span><span class="ins">A</span> <var>qualified-id</var> in which the <var>nested-name-specifier</var> names a dependent type that is not the current instantiation.</li>
  
  <li><span class="ins">A <var>qualified-id</var> in which the <var>nested-name-specifier</var> refers to the current instantiation, the current instantiation has at least one dependent base class, and name lookup of the <var>qualified-id</var> does not find any member of the current instantiation or a non-dependent base class thereof.</span></li>

  <li><span class="ins">An <var>id-expression</var> denoting the member in a class member access expression (5.2.5 [expr.ref]) in which either</span>
  <ul>
    <li><span class="ins">the type of the object expression is the current instantiation, the current instantiation has at least one dependent base class, and name lookup of the <var>id-expression</var> does not find a member of the current instantiation or a non-dependent base class thereof; or</span></li>
    <li><span class="ins">the type of the object expression is dependent and is not the current instantiation.</span></li>
  </ul></li>
</ul>
</OL>

<p>Add the following new paragraphs after 14.6.2.1 [temp.dep.type] paragraph 5:</p>

<ul>
  <li><span class="ins">If a <var>qualified-id</var> in which the <var>nested-name-specifier</var> refers to the current instantiation is not a member of the current instantiation or a member of an unknown specialization, the program is ill-formed even if the template containing the <var>qualified-id</var> is not instantiated; no diagnostic required. Similarly, if the <var>id-expression</var> in a class member access expression for which the type of the object expression is the current instantiation does not refer to a member of the current instantiation or a member of an unknown specialization, the program is ill-formed even if the template containing the member access expression is not instantiated; no diagnostic required. [<i>Example</i>:</span>
  <pre>
<span class="ins">template&lt;typename T&gt; class A {</span>
  <span class="ins">typedef int type;</span>
  <span class="ins">void f() {</span>
    <span class="ins">A&lt;T&gt;::type i; <i>// okay: refers to a member of the current instantiation</i></span>
    <span class="ins">typename A&lt;T&gt;::other j; <i>// error: neither a member of the current instantiation nor a member of an unknown specialization</i></span>
  <span class="ins">}</span>
<span class="ins">};</span>
</pre>
  <span class="ins">- <i>end example</i>]</span></li>

  <li><span class="ins">If, for a given set of template arguments, a specialization of a template is instantiated that refers to a member of the current instantiation with a <var>qualified-id</var> or class member access expression, the name in the <var>qualified-id</var> or class member access expression is looked up in the template instantiation context. If the result of this lookup differs from the result of name lookup in the template definition context, name lookup is ambiguous. [<i>Note</i>: the result of name lookup differs only when the member of the current instantiation was found in a non-dependent base class of the current instantiation, and a member with the same name is also introduced by the substitution for a dependent base class of the current instantiation. - <i>end note</i>]</span></li>
</ul>

<p>Modify 14.6.2.2 [temp.dep.expr] paragraph 5 as follows:</p>

<ol start="5">
  <li>A class member access expression (5.2.5 [expr.ref]) is type-dependent if <span class="ins">the expression refers to a member of the current instantiation and the</span> type of the referenced member is dependent<span class="ins">, or the class member access expression refers to a member of an unknown specialization</span>.  
  [ <i>Note</i>: in an expression of the form <code>x.y</code> or <code>xp-&gt;y</code> the type of the expression is usually the type of the member <code>y</code> of the 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. - <i>end note</i> ]</li>
</ol>

<p>Modify 14.6.2.4 [temp.dep.temp] paragraph 4 as follows:</p>

<ol start="4">
  <li>A template <var>template-argument</var> is dependent if it names a <var>template-parameter</var> or is a <var>qualified-id</var> <span class="del">with a
<var>nested-name-specifier</var> which contains a <var>class-name</var> or a <var>decltype-specifier</var> that denotes a dependent type</span><span class="ins">that refers to a member of an unknown specialization</span>.</li>
</ol>

</body>
</html>
 