<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US"><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Nameless parameters and unutterable specializations</title>

<style type="text/css">
body { color: #000000; background-color: #FFFFFF; max-width: 40em; }
del, .del { text-decoration: line-through; color: #8B0040; }
ins, .ins { text-decoration: underline; color: #005100; }

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }

p.function { }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; }

blockquote.std, ul.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.std del, blockquote.std .del, ul.std del, ul.std .del { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC; }
blockquote.std ins, blockquote.std .ins, ul.std ins, ul.std .ins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3;
  padding-left: 0.5em; padding-right: 0.5em; }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto; }
th { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }
td { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }

table.table { border-spacing: 2px; border-collapse: separate; }
.table * th, .table * td { border: 1px solid black; }

table.frontmatter { border: 0; border-spacing: 0px; border-collapse: collapse; margin: 0; width: 619px; }
.frontmatter * td, .frontmatter * th { padding: 0px; }
.frontmatter * th { font-weight: inherit; text-align: left; vertical-align: top; }

ul.dash { list-style-type: none; }
ul.dash li:before { content: '\2014'; margin-left: -1em }

span.highlight { background-color: #7FDFFF }

.nowrap { white-space: nowrap; }

code.prettyprint { background-color: #F1F1F1; border-width: 1px; border-style: none dotted; border-color: #787878; padding: 0 0.25em 0 0.25em; }
pre.proportional { font-family: inherit; font-size: inherit; }
</style>

<script type="text/javascript" src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
</head>

<body>
<h1>Nameless parameters and unutterable specializations</h1>
<table class="frontmatter"><tbody>
    <tr>
        <th>Document number:</th>
        <td>P0736R1</td>
    </tr>
    <tr>
        <th>Date:</th>
        <td>2018-05-05</td>
    </tr>
    <tr>
        <th>Project:</th>
        <td>ISO/IEC JTC 1/SC 22/WG 21/C++</td>
    </tr>
    <tr>
        <th>Audience subgroup:</th>
        <td>Evolution</td>
    </tr>
    <tr>
        <th>Revises:</th>
        <td>P0736R0</td>
    </tr>
    <tr>
        <th>Reply-to:</th>
        <td><span class="nowrap">Hubert S.K. Tong</span> &lt;<a href="mailto:hubert.reinterpretcast@gmail.com">hubert.reinterpretcast@gmail.com</a>&gt;</td>
    </tr>
</tbody></table>

<h2>Changelog</h2>
<h3>Changes from R0</h3>
<ul><li>Replaced conjunction with disjunction in the <code class="prettyprint lang-cpp">int::value</code> example demonstrating unutterable specializations under Concepts.</li
><li>Replaced the <code class="prettyprint lang-cpp">[<i>name</i>]</code> syntax, which need further refinement to resolve parsing issues, with a
<code class="prettyprint lang-cpp">for &lt;...&gt;</code> syntax.</li
><li>Added a note on the status of constraints in partial ordering.</li
><li>Added alternate placement of the <i>requires-clause</i> as a possible strategy.</li
><li>Added an example of explicitly specializing a member of a partial specialization.</li
><li>Added acknowledgements.</li
></ul>

<h2>Issue/Background</h2>

<p>When an expression is part of a signature for a function template, whether expressions are equivalent for the purposes of resolving declarations of the same entity to each other is defined by [temp.over.link].
This definition in turn relies on the form of the expression in the style of the one-definition rule ([basic.def.odr]).</p>

<p>Unfortunately, it is not specified what form an expression takes when template parameters are substituted with their corresponding arguments.
Indeed, with the addition of <i>requires-clause</i>s, substitution might not occur in certain subexpressions.
This frustrates the ability to form redeclarations in contexts where certain template parameters have no name, such as when an enclosing template is explicitly specialized.
Redeclarations in such contexts also obfuscate the relationship between declarations expressed in terms of the primary template and declarations expressed with reference to specializations.</p>


<h2>Current implementation behaviour</h2>

<p>Even without the addition of Concepts, it is possible to encounter the problem of lacking a suitable way to form equivalent corresponding expressions in redeclarations.</p>

<p>For example, given:</p>
<pre class="prettyprint lang-cpp"
>template &lt;unsigned N&gt;
struct TA {
  template &lt;unsigned M&gt;
  void f(unsigned (*)[N + M]);
};</pre>

<p>An attempt to produce an explicit specialization of <code class="prettyprint lang-cpp">f</code> for <code class="prettyprint lang-cpp">TA&lt;0&gt;</code> might yield:</p>
<pre class="prettyprint lang-cpp"
>template &lt;&gt;
template &lt;unsigned M&gt;
void TA&lt;0&gt;::f(unsigned (*)[0u + M]);</pre>

<p>Indeed, it happens to work with both GCC and Clang.
Unfortunately, not all literal types can necessarily have their values expressed as integer literals of the type (<code class="prettyprint lang-cpp">short</code> comes to mind).
In any case, it only happens to work and may stop working at any time.
GCC (at least as late as version 7.2 from August 2017) would have accepted <code class="prettyprint lang-cpp">0</code> in place of <code class="prettyprint lang-cpp">0u</code>
despite the type mismatch (so the <code class="prettyprint lang-cpp">short</code> conundrum was somewhat sidestepped), but no longer does so.</p>

<p>Now with the addition of Concepts, an additional complication appears.</p>
<p>Given:</p>
<pre class="prettyprint lang-cpp"
>template &lt;typename T&gt;
struct TB {
  template &lt;typename U&gt;
  void f() requires U::value || T::value;
};</pre>

<p>A similar approach to forming the explicit specialization of <code class="prettyprint lang-cpp">f</code> for <code class="prettyprint lang-cpp">TB&lt;int&gt;</code>
would create the unutterable <code class="prettyprint lang-cpp">int::value</code>.
No implementation of Concepts known to the author accepts the utterance of <code class="prettyprint lang-cpp">int::value</code>.</p>


<h2>Possible solutions</h2>

<p>It is the hope of the author that either
a solution is adopted to ease the formation of related declarations or
the effective inability to produce truly equivalent expressions in said contexts is made clear through examples to be incorporated into the Standard.</p>

<p>In the pursuit of a solution, syntax to allow binding of a name for specialized template arguments of the primary template could be explored.</p>
<p>In the context of the above cases, such syntax might look like the following (with the name appearing as a label in a context from which the argument of the specialization can be deduced):</p>
<pre class="prettyprint lang-cpp"
>template &lt;&gt;
template &lt;unsigned M&gt;
void TA&lt;N: 0&gt;::f(unsigned (*)[N + M]);

template &lt;&gt;
template &lt;typename U&gt;
void TB&lt;T: int&gt;::f() requires U::value || T::value;</pre>

<p>Notice that in the latter case, <code class="prettyprint lang-cpp">T</code> would need to be treated as dependent.</p>

<p>Such a binding could also allow for partial specializations to have constraints expressed in terms of the parameters to the primary template. Below, in order to introduce the names before their use,
the argument list for the specialization is introduced within the <i>template-head</i>; the <i>simple-template-id</i> then names the specialization using the bound names:</p>
<pre class="prettyprint lang-cpp"
>template &lt;typename T, typename U&gt;
struct A;

template &lt;typename TT, typename UU&gt; for &lt;T: TT *, U: UU&gt;
requires C&lt;T, U&gt;
struct A&lt;T, U&gt; { };

template &lt;typename TT, typename UU&gt; for &lt;T: TT, U: UU *&gt;
requires C&lt;T, U&gt; &amp;&amp; C1&lt;T&gt;
struct A&lt;T, U&gt; { };</pre>

<p>Without the binding, the intended subsumption of <code class="prettyprint lang-cpp">C&lt;T, U&gt;</code> in the first specialization by the <i>requires-clause</i> of the second would be muddied;
however, because partial ordering only considers constraints after deduction in both directions succeed, the subsumption does not come into play<sup id="noteref_001"><a href="#note_001">[1]</a></sup>.</p>

<p>In any case, the syntax for introducing names could also be used for explicit specializations of members of partial specializations; the binding list then binds arguments for the parameters of the partial specialization:</p>
<pre class="prettyprint lang-cpp"
>template &lt;unsigned N&gt;
struct A&lt;TA&lt;N + 1&gt;, TA&lt;N&gt; &gt; {
  template &lt;unsigned M, int (*)[N]&gt;
  TA&lt;N + M&gt; *f(unsigned (*)[N + M]);
};

template &lt;&gt; for &lt;N: 42&gt;
template &lt;unsigned M, int (*)[N]&gt;
TA&lt;N + M&gt; *A&lt;TA&lt;N + 1&gt;, TA&lt;N&gt; &gt;::f(unsigned (*)[N + M]) { return 0; }</pre>
<p>Consideration needs to be given to that fact that the type associated with the introduced name is not known until it is used in the corresponding component of the <i>nested-name-specifier</i>.</p>

<p><i>Thus we speak the unutterable and name the nameless.</i></p>


<h2>Further possibilities</h2>
<h3>Generalizing the <code class="prettyprint lang-cpp">for &lt;...&gt;</code> syntax</h3>
<p>The <code class="prettyprint lang-cpp">for &lt;...&gt;</code>
syntax can be generalized under a model where specializations are declared like redeclarations of the primary template,
with the new syntax providing both a proxy of the template parameter list (with or without names of the parameters) for the &#x201c;redeclaration&#x201d; and the arguments of the specialization.</p>
<pre class="proportional prettyprint lang-cpp"><code
>template &lt;unsigned N&gt; for &lt;TA&lt;N + 1&gt;, TA&lt;N&gt; &gt; struct A;
template &lt;unsigned N&gt; struct A&lt;TA&lt;N + 1&gt;, TA&lt;N&gt; &gt;;</code>  <i>// redeclaration</i></pre>

<h3>Alternate placement of the <i>requires-clause</i></h3>
<p>The short syntax can be used for partial specialization with constraints by deferring the <i>requires-clause</i> until after the <i>simple-template-id</i>.</p>
<pre class="prettyprint lang-cpp"
>template &lt;typename TT, typename UU&gt;
struct A&lt;T: TT *, U: UU&gt; requires C&lt;T, U&gt;;

template &lt;typename TT, typename UU&gt;
struct A&lt;T: TT, U: UU *&gt; requires C&lt;T, U&gt; &amp;&amp; C1&lt;T&gt;;

template &lt;typename&gt; int v;
template &lt;typename U&gt; int v&lt;T: U *&gt; requires C1&lt;T&gt; = 0;</pre>


<h2>Acknowledgements</h2>
<p>The author thanks Richard Smith for his input at the Jacksonville meeting of 2018 and his further contribution
(including that of the <code class="prettyprint lang-cpp">for &lt;...&gt;</code> syntax)
in the preparation of this paper.
As usual, any remaining mistakes are the responsibility of the author.</p>


<h2>Notes</h2>
<ol><li id="note_001"><span class="backlink"><b><a href="#noteref_001">^</a></b></span
> This is necessary for partial ordering of function templates, since there is no established relationship in that case for constraints expressed in terms of the template parameters of one template
to be matched with those expressed in terms of the template parameters of another template.
The author believes that partial ordering of class template partial specializations can consider constraints without deduction succeeding in both directions when a mapping like the one proposed by this paper is present.</li
></ol></body></html>
