<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
	"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  <title>Proposed resolution of core issue 301</title>
  <style type="text/css">
.inserted {
	text-decoration: underline;
}
.deleted {
	text-decoration: line-through;
}
.upper-roman {
	list-style-type: upper-roman;
}
.upper-alpha {
	list-style-type: upper-alpha;
}
.arabic {
	list-style-type: arabic;
}
.lower-alpha {
	list-style-type: lower-alpha;
}
li {
	margin-top: 1em;
}
</style>
</head>

<body>

<table summary="This table provides identifying information for this
		document.">
<tr>
<th>Doc. No.:</th>
<td>WG21/N1801, J16/05-0061</td>
</tr>
<tr>
<th>Date:</th>
<td>2005-05-02</td>
</tr>
<tr>
<th>Reply to:</th>
<td>Clark Nelson</td>
</tr>
<tr>
<th>Phone:</th>
<td>+1-503-712-8433</td>
</tr>
<tr>
<th>Email:</th>
<td><a href="mailto:clark.nelson@intel.com">clark.nelson@intel.com</a></td>
</tr>
</table>
<h1>Proposed resolution of core issue 301</h1>

<h2>Primary changes for operator function templates</h2>

<p>The principle behind these proposed edits is to change the definition of <var>
  template-id</var> to include <var>operator-function-id</var> cases. <var>class-template-id</var> 
  is introduced as an equivalent to the previous <var>template-id</var>, where the 
  name of the template is restricted to an identifier.</p>

<ol class="upper-alpha">
<li>
<p>Change the definition of <var>operator-function-id</var> (13.5p1):</p>

<blockquote>
<dl>
<dt><dfn>operator-function-id:</dfn></dt>
<dd><code>operator</code> <var>operator</var></dd>
<dd><span class="deleted"><code>operator</code> <var>operator</var> <code>&lt;</code>
<var>template-argument-list<sub>opt</sub></var> <code>&gt;</code></span></dd>
</dl>
</blockquote>
<p>This undoes the grammar change that was made for core issue 38.</p>

</li>
<li>
<p>Change the definition of <var>template-id</var> and add a definition of <var>
  class-template-id</var> (14.2p1):</p>

<blockquote>
<dl>
<dt><dfn>template-id:</dfn></dt>
<dd><var>template-name</var> <code>&lt;</code> <var>template-argument-list<sub>opt</sub></var>
<code>&gt;</code></dd>
<dd><span class="inserted"><var>operator-function-id</var> <code>&lt;</code> <var>template-argument-list<sub>opt</sub></var>
<code>&gt;</code></span></dd>
</dl>
<dl class="inserted">
<dt><dfn>class-template-id:</dfn></dt>
<dd><var>template-name</var> <code>&lt;</code> <var>template-argument-list<sub>opt</sub></var>
<code>&gt;</code></dd>
</dl>
</blockquote>
</li>
<li>
<p>Change 13.5p1:</p>

<blockquote>
<p>A function declaration having one of the following <var>operator-function-ids</var> 
  as its name declares an <dfn>operator function</dfn>. <ins>A function template 
  declaration having one of the following <var>operator-function-ids</var> as its 
  name declares an <dfn>operator function template</dfn>. A specialization of an 
  operator function template is also an operator function.</ins> An operator function 
  is said to <dfn>implement</dfn> the operator named in its <var>operator-function-id</var>.</p>

</blockquote>
</li>
<li>
<p>Change 14.2p3:</p>

<blockquote>
<p>After name lookup (3.4) finds that a name is a <var>template-name</var>,
  <span class="inserted">or refers to a set of overloaded functions any member of 
  which is a function template,</span> if this name is followed by a <code>&lt;</code>, 
  the <code>&lt;</code> is always taken as the <span class="deleted">beginning</span>
  <span class="inserted">delimiter</span> of a <var>template-argument-list</var> 
  and never as <span class="deleted">a name followed by</span> the less-than operator. 
  When parsing a <span class="deleted"><var>template-id</var></span>
  <span class="inserted"><var>template-argument-list</var></span>, the first non-nested
  <code>&gt;</code><sup>131)</sup> is taken as the <span class="deleted">end of the
  <var>template-argument-list</var></span> <span class="inserted">ending delimiter</span> 
  rather than a greater-than operator.</p>

</blockquote>
</li>
</ol>
<h2>Secondary changes: references to <var>template-id</var> which should be to
  <var>class-template-id</var></h2>

<p>References from the grammar are presented first.</p>

<ol class="arabic">
<li>
<p>Change the definition of <var>nested-name-specifier</var> (5.1p7):</p>

<blockquote>
<dl>
<dt><dfn>nested-name-specifier:</dfn></dt>
<dd><var>type-name</var> <code>::</code></dd>
<dd><var>namespace-name</var> <code>::</code></dd>
<dd><var>nested-name-specifier</var> <var>identifier</var> <code>::</code></dd>
<dd><var>nested-name-specifier</var> <code>template</code><sub><var>opt</var></sub>
<var><span class="inserted">class-</span>template-id</var> <code>::</code></dd>
</dl>
</blockquote>
</li>
<li>
<p>Change the definition of <var>pseudo-destructor-name</var> (5.2p1):</p>

<blockquote>
<dl>
<dt><dfn>pseudo-destructor-name:</dfn></dt>
<dd><code>::</code><var><sub>opt</sub> nested-name-specifier<sub>opt</sub> type-name</var>
<code>:: ~</code> <var>type-name</var></dd>
<dd><code>::</code><var><sub>opt</sub> nested-name-specifier</var> <code>template</code>
<var><span class="inserted">class-</span>template-id</var> <code>:: ~</code>
<var>type-name</var></dd>
<dd><code>::</code><var><sub>opt</sub> nested-name-specifier<sub>opt</sub></var>
<code>~</code> <var>type-name</var></dd>
</dl>
</blockquote>
</li>
<li>
<p>Change the definition of <var>simple-type-specifier</var> (7.1.5.2p1):</p>

<blockquote>
<dl>
<dt><dfn>simple-type-specifier:</dfn></dt>
<dd><code>::</code><var><sub>opt</sub> nested-name-specifier<sub>opt</sub> type-name</var></dd>
<dd><code>::</code><var><sub>opt</sub> nested-name-specifier</var> <code>template</code>
<var><span class="inserted">class-</span>template-id</var></dd>
<dd><code>char</code></dd>
<dd><code>wchar_t</code></dd>
<dd><code>bool</code></dd>
<dd><code>short</code></dd>
<dd><code>int</code></dd>
<dd><code>long</code></dd>
<dd><code>signed</code></dd>
<dd><code>unsigned</code></dd>
<dd><code>float</code></dd>
<dd><code>double</code></dd>
<dd><code>void</code></dd>
</dl>
</blockquote>
</li>
<li>
<p>Change the definition of <var>elaborated-type-specifier</var> (7.1.5.3):</p>

<blockquote>
<dl>
<dt><dfn>elaborated-type-specifier:</dfn></dt>
<dd><var>class-key</var> <code>::</code><var><sub>opt</sub> nested-name-specifier<sub>opt</sub> 
identifier</var></dd>
<dd><var>class-key</var> <code>::</code><var><sub>opt</sub> nested-name-specifier<sub>opt</sub></var>
<code>template</code><var><sub>opt</sub> <span class="inserted">class-</span>template-id</var></dd>
<dd><code>enum ::</code><var><sub>opt</sub> nested-name-specifier<sub>opt</sub> 
identifier</var></dd>
</dl>
</blockquote>
</li>
<li>
<p>Change the definition of <var>class-name</var> (9p1):</p>

<blockquote>
<dl>
<dt><dfn>class-name:</dfn></dt>
<dd><var>identifier</var></dd>
<dd><var><span class="inserted">class-</span>template-id</var></dd>
</dl>
</blockquote>
</li>
<li>
<p>Change the definition of <var>class-head</var> (9p1):</p>

<blockquote>
<dl>
<dt><dfn>class-head:</dfn></dt>
<dd><var>class-key identifier<sub>opt</sub> base-clause<sub>opt</sub></var></dd>
<dd><var>class-key nested-name-specifier identifier base-clause<sub>opt</sub></var></dd>
<dd><var>class-key nested-name-specifier<sub>opt</sub> <span class="inserted">class-</span>template-id 
base-clause<sub>opt</sub></var></dd>
</dl>
</blockquote>
</li>
<li>
<p>Change the definition of <var>typename-specifier</var> (14.6p3):</p>

<blockquote>
<dl>
<dt><dfn>typename-specifier:</dfn></dt>
<dd><code>typename ::</code><var><sub>opt</sub> nested-name-specifier identifier</var></dd>
<dd><code>typename ::</code><var><sub>opt</sub> nested-name-specifier</var>
<code>template</code><var><sub>opt</sub> <span class="inserted">class-</span>template-id</var></dd>
</dl>
</blockquote>
</li>
<li>
<p>Change 3.3.1p3:</p>

<blockquote>
<p>The point of declaration for a class first declared by a <var>class-specifier</var> 
  is immediately after the identifier or <var><span class="inserted">class-</span>template-id</var> 
  (if any) in its <var>class-head</var> (Clause 9). The point of declaration for 
  an enumeration is immediately after the <var>identifier</var> (if any) in its
  <var>enum-specifier</var> (7.2).</p>

</blockquote>
</li>
<li>
<p>Change 3.4.5p6:</p>

<blockquote>
<p>If the <var>nested-name-specifier</var> contains a <span class="deleted">class
  <var>template-id</var></span> <span class="inserted"><var>class-template-id</var></span> 
  (14.2), <span class="inserted">the names in</span> its <var>template-arguments</var> 
  are <span class="deleted">evaluated</span> <span class="inserted">looked up</span> 
  in the context in which the <span class="deleted">entire <var>postfix-expression</var></span>
  <span class="inserted"><var>nested-name-specifier</var></span> occurs.</p>

</blockquote>
</li>
<li>
<p>Change the grammar-like portion of 7.1.5.3p1:</p>

<blockquote>
<dl>
<dd><var>class-key identifier</var> <code>;</code></dd>
<dd><code>friend</code> <var>class-key</var> <code>::</code><var><sub>opt</sub> 
identifier</var> <code>;</code></dd>
<dd><code>friend</code> <var>class-key</var> <code>::</code><var><sub>opt</sub>
<span class="inserted">class-</span>template-id</var> <code>;</code></dd>
<dd><code>friend</code> <var>class-key</var> <code>::</code><var><sub>opt</sub> 
nested-name-specifier identifier</var> <code>;</code></dd>
<dd><code>friend</code> <var>class-key</var> <code>::</code><var><sub>opt</sub> 
nested-name-specifier</var> <code>template</code><var><sub>opt</sub>
<span class="inserted">class-</span>template-id</var> <code>;</code></dd>
</dl>
</blockquote>
</li>
<li>
<p>Change 14.2p6:</p>

<blockquote>
<p>A <var><span class="inserted">class-</span>template-id</var> that names a class 
  template specialization is a <var>class-name</var> (clause 9).</p>

</blockquote>
</li>
<li>
<p>Change the first sentence of 14.5.4p1:</p>

<blockquote>
<p>A primary class template declaration is one in which the class template name 
  is an identifier. A template declaration in which the class template name is a
  <var><span class="inserted">class-</span>template-id</var>, is a partial specialization 
  of the class template named in the <var><span class="inserted">class-</span>template-id</var>.
  <var>...</var></p>

</blockquote>
</li>
<li>
<p>Change the last bullet of 14.6.2.1p6:</p>

<blockquote>
<p>a <var><span class="inserted">class-</span>template-id</var> 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.</p>

</blockquote>
</li>
<li>
<p>Change 14.7p3:</p>

<blockquote>
<p>An explicit specialization may be declared for a function template, a class template, 
  a member of a class template or a member template. An explicit specialization 
  declaration is introduced by <code>template&lt;&gt;</code>. In an explicit specialization 
  declaration for a class template, a member of a class template or a class member 
  template, the name of the class that is explicitly specialized shall be a <var>
  <span class="inserted">class-</span>template-id</var>. In the explicit specialization 
  declaration for a function template or a member function template, the name of 
  the function or member function explicitly specialized may be a <var>template-id</var>.</p>

</blockquote>
</li>
<li>
<p>Change 14.7.3p9:</p>

<blockquote>
<p>A <var><span class="inserted">class-</span>template-id</var> that names a class 
  template explicit specialization that has been declared but not defined can be 
  used exactly like the names of other incompletely-defined classes (3.9).</p>

</blockquote>
</li>
<li>
<p>Change the last bullet of 14.8.2.1p4:</p>

<blockquote>
<p>If P is a class, and P has the form <var><span class="inserted">class-</span>template-id</var>, 
  then A can be a derived class of the deduced A. Likewise, if P is a pointer to 
  a class of the form <var><span class="inserted">class-</span>template-id</var>, 
  A can be a pointer to a derived class pointed to by the deduced A.</p>

</blockquote>
</li>
</ol>
<h2>Other secondary changes</h2>

<p></p>

<ol class="lower-alpha">
<li>
<p>Change 3.4.3.1p1, third bullet:</p>

<blockquote>
<p>the <span class="inserted">names in a</span> <var>template-argument</var> of 
  a <var>template-id</var> are looked up in the context in which the
  <span class="deleted">entire <var>postfix-expression</var></span>
  <span class="inserted"><var>qualified-id</var></span> occurs.</p>

</blockquote>
<p>This is just editorial clarification.</p>

</li>
<li>
<p>Change 3.4.3.2p1:</p>

<blockquote>
<p>If the <var>nested-name-specifier</var> of a <var>qualified-id</var> nominates 
  a namespace, the name specified after the <var>nested-name-specifier</var> is 
  looked up in the scope of the namespace, except that the
  <span class="inserted">names in a</span> <var>template-argument</var> of a
  <var>template-id</var> are looked up in the context in which the
  <span class="deleted">entire <var>postfix-expression</var></span>
  <span class="inserted"><var>qualified-id</var></span> occurs.</p>

</blockquote>
<p>This is just editorial clarification.</p>

</li>
<li>
<p>Change 14p2:</p>

<blockquote>
<p>A <var>template-declaration</var> can appear only as a namespace scope or class 
  scope declaration. In a function template declaration, the
  <span class="inserted">last component of the</span> <var>declarator-id</var> shall 
  be a <var>template-name</var> <span class="inserted">or <var>operator-function-id</var></span> 
  (i.e., not a <var>template-id</var>). <var>[ Note:</var> in a class template declaration, 
  if the class name is a <var><span class="inserted">class-</span>template-id</var>, 
  the declaration declares a class template partial specialization (14.5.4).
  <var>&#8212;end note ]</var></p>

</blockquote>
</li>
<li>
<p>Change 14.3p1:</p>

<blockquote>
<p>There are three forms of <var>template-argument</var>, corresponding to the three 
  forms of <var>template-parameter</var>: type, non-type and template. The type 
  and form of each <var>template-argument</var> specified in a <var>template-id</var>
  <span class="inserted">or <var>class-template-id</var></span> shall match the 
  type and form specified for the corresponding parameter declared by the template 
  in its <var>template-parameter-list</var>.</p>

</blockquote>
<p>From a bottom-up perspective, <var>template-id</var> would seem practically to 
  include <var>class-template-id</var>, so this addition might seem to be redundant. 
  However, from a top-down perspective, some contexts require a <var>template-id</var>, 
  and others require a <var>class-template-id</var>, so they are actually disjoint.</p>

</li>
<li>
<p>Change 14.4p1:</p>

<blockquote>
<p>Two <var>template-ids</var> <span class="inserted">or <var>class-template-ids</var></span> 
  refer to the same class or function if <var>...</var></p>

</blockquote>
<p>Note that 14.4p1 is also heavily modified by the proposed resolution of core 
  issue 354.</p>

</li>
<li>
<p>Delete 14.5p1:</p>

<blockquote class="deleted">
<p>A <var>template-id</var>, that is, the <var>template-name</var> followed by a
  <var>template-argument-list</var> shall not be specified in the declaration of 
  a primary template declaration. <var>[ Example:</var></p>

<pre>template&lt;class T1, class T2, int I&gt; class A&lt;T1, T2, I&gt; { }; // error
template&lt;class T1, int I&gt; void sort &lt;T1, I&gt;(T1 data[I]); // error</pre>
<p><var>&#8212;end example ] [ Note:</var> however, this syntax is allowed in class template 
  partial specializations (14.5.4). <var>&#8212;end note ]</var></p>

</blockquote>
<p>This provision is vacuous, because by the definition of primary in 14.5.4p1, 
  it is impossible to violate: if there is a <var>template-argument-list</var> (or 
  delimiters for same) in a class template declaration, it is not a primary declaration. 
  Furthermore, 14.5.4p1 also already contains the requirement that the primary declaration 
  must precede any partial specialization, so there would be no point in trying 
  to reword this to refer to the first declaration of a template.</p>

</li>
<li>
<p>Change the second bullet of 14.6.2.2p3:</p>

<blockquote>
<p>a <var>template-id</var> <span class="inserted">or <var>class-template-id</var></span> 
  that is dependent,</p>

</blockquote>
</li>
<li>
<p>Change 14.7.2p2:</p>

<blockquote>
<p><span class="deleted">If the explicit instantiation is for a class, a function 
  or a member template specialization,</span> <span class="inserted">If the explicit 
  instantiation is for a class or member class, the <var>elaborated-type-specifier</var> 
  in the <var>declaration</var> shall include a <var>class-template-id</var>. If 
  the explicit instantiation is for a function or member function,</span> the
  <var>unqualified-id</var> in the declaration shall be either a <var>template-id</var> 
  or, where all template arguments can be deduced, a <var>template-name</var>.
  <var>[ Note:</var> the declaration may declare a <var>qualified-id</var>, in which 
  case the <var>unqualified-id</var> of the <var>qualified-id</var> must be a
  <var>template-id</var>. <var>&#8212;end note ]</var> If the explicit instantiation is 
  for a member function, a member class or a static data member of a class template 
  specialization, the name of the class template specialization in the <var>qualified-id</var> 
  for the member name shall be a <var><span class="inserted">class-</span>template-id</var>. 
  An explicit instantiation shall appear in an enclosing namespace of its template. 
  If the name declared in the explicit instantiation is an unqualified name, the 
  explicit instantiation shall appear in the namespace where its template is declared.
  <var>[ Note:</var> regarding qualified names in declarators, see 8.3. <var>&#8212;end 
  note ]</var></p>

</blockquote>
<p>The problem here is that in an explicit instantiation of a class (or member class), 
  there is no <var>unqualified-id</var>, at least not at the top level. So I broke 
  out the class case separately from the function case. Note also an added reference 
  to <var>class-template-id</var>.</p>

</li>
</ol>

</body>

</html>
