<?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">
<!--DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN"
       "http://www.w3.org/TR/xhtml-basic/xhtml-basic10.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 (revision 1)</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;
}
.decimal {
	list-style-type: decimal;
}
.lower-alpha {
	list-style-type: lower-alpha;
}
li {
	margin-top: 1em;
}</style>
</head>

<body>

<table
summary="This table provides identifying information for this   document.">
  <tbody>
    <tr>
      <th>Doc. No.:</th>
      <td>WG21/N1896, J16/05-0156</td>
    </tr>
    <tr>
      <th>Date:</th>
      <td>2005-10-13</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>
  </tbody>
</table>

<h1>Proposed resolution of core issue 301 (revision 1)</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>simple-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>Rename <var>template-id</var> to <var>simple-template-id</var>, and
    add a new definition for <var>template-id</var> (14.2p1):</p>

    <blockquote>
      <dl>
        <dt><dfn><span class="inserted">simple-</span>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>

      <div class="inserted">
      <dl>
        <dt><dfn>template-id:</dfn></dt>
          <dd><var>simple-template-id</var></dd>
          <dd><var>operator-function-id</var> <code>&lt;</code>
            <var>template-argument-list<sub>opt</sub></var>
          <code>&gt;</code></dd>
      </dl>
      </div>
    </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>. <span class="inserted">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.</span> 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 that an
      <var>operator-function-id</var> refers to a set of overloaded functions
      any member of which is a function template,</span> if this <span
      class="deleted">name</span> 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>simple-template-id</var></h2>

<p>References from the grammar are presented first.</p>
<ol class="decimal">
  <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">simple-</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">simple-</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">simple-</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">simple-</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">simple-</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">simple-</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">simple-</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">simple-</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>simple-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">simple-</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">simple-</span>template-id</var>
          <code>;</code></dd>
      </dl>
    </blockquote>
  </li>
  <li><p>Change 14.2p6:</p>

    <blockquote>
      <p>A <var><span class="inserted">simple-</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">simple-</span>template-id</var>, is a partial
      specialization of the class template named in the <var><span
      class="inserted">simple-</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">simple-</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">simple-</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">simple-</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">simple-</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">simple-</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">simple-</span>template-id</var>, the declaration
      declares a class template partial specialization (14.5.4).
      <var>&#x2014;end note ]</var></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>simple-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> <span class="inserted">or
      <var>operator-function-id</var></span>. <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>&#x2014;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">simple-</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>&#x2014;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>simple-template-id</var>.</p>
  </li>
</ol>
</body>
</html>
