<!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>Proposed resolution for 2019 comment CA 112</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: #FFCCCC;
  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: #FFCCCC;
  border: 1px solid #ECD7EC;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stdins { text-decoration: none;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3;
  padding-left: 0.5em; padding-right: 0.5em; }
li.stdins { text-decoration: none;
  color: #000000; background-color: #C8FFC8; }
li.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFCCCC; }

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 }
span.grammar { font-family: sans-serif; font-style: italic; font-size: 83.3%; }

.nowrap { white-space: nowrap; }
.pre { white-space: pre; }

pre { font-family: inherit; }
code { font-style: normal !important; }

.subtitle { font-size: 80%; }

#xins1:checked ~ * ins { display: none; visibility: hidden }
#xdel1:checked ~ * del { display: none; visibility: hidden }
#xins2:checked ~ * ins { display: none; visibility: hidden }
#xdel2:checked ~ * del { display: none; visibility: hidden }
</style>

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

<body>
<h1>Proposed resolution for 2019 comment CA 112</h1>
<table class="frontmatter"><tbody>
    <tr>
        <th>Document number:</th>
        <td>P2113R0</td>
    </tr>
    <tr>
        <th>Date:</th>
        <td>2020-02-13</td>
    </tr>
    <tr>
        <th>Project:</th>
        <td>ISO/IEC JTC 1/SC 22/WG 21/C++</td>
    </tr>
    <tr>
        <th>Audience subgroup:</th>
        <td>Core</td>
    </tr>
    <tr>
        <th>Revises:</th>
        <td><i>None</i></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>Notes</h2>
<p>Consistent with the direction from Belfast (and the proposed change submitted with CA 112),
the property of &#x201c;structural&#x201d; partial ordering
that it ignores the form of function parameters for which arguments are not provided on the call expression
is not replicated in the consideration of constraints.
The form of such function parameters are not ignored for the case of non-template (but templated) functions.
There is also no precedent for handling the constraints that relate to such function parameters
(e.g., if there are constraints that involve template parameters for either template that are without a deduced argument
after the two-way deduction process)
in a way that they are ignored.</p>

<p>This also resolves (with modification) comment US 120.</p>

<h2>Proposed Wording</h2>

<div><input type="checkbox" id="xins1" /><label for="xins1">Hide text inserted in-line</label>
<input type="checkbox" id="xdel1" /><label for="xdel1">Hide text deleted in-line</label><!--

--><p>In relation to N4849, modify in subclause 13.7.6.1 [temp.over.link] paragraph 6:</p
><blockquote class="std">

<p>
Two <span class="grammar">template-head</span>s are <i>equivalent</i> if their
<span class="grammar">template-parameter-list</span>s have the same length, corresponding
<span class="grammar">template-parameter</span>s are equivalent<ins> and such that
if either <span class="grammar">template-parameter</span> is declared with a
<span class="grammar">type-constraint</span>, they are both declared with
<span class="grammar">type-constraint</span>s that are equivalent</ins>, and if either<ins>
<span class="grammar">template-head</span></ins> has a
<span class="grammar">requires-clause</span>, they both have <span class="grammar">requires-clause</span>s
and the corresponding <span class="grammar">constraint-expression</span>s are equivalent.
Two <span class="grammar">template-parameter</span>s are <i>equivalent</i> under
the following conditions:</p>
<ul class="dash">
<li>
[ &#x2026; ]</li><li>
if they declare non-type template parameters, they have equivalent types<ins>
ignoring the use of <span class="grammar">type-constraint</span>s for placeholder types</ins>,<ins> and</ins></li>
<li>
if [ &#x2026; ]<del>, and</del></li><li><del>
if either is declared with a
<span class="grammar">type-constraint</span>, they both are, and the
<span class="grammar">type-constraint</span>s are equivalent</del>.</li>
</ul>
<p>[ &#x2026; ]</p>

</blockquote
><p>In relation to N4849, modify in subclause 13.7.6.2 [temp.func.order] paragraph 2:</p
><blockquote class="std">

<p>Partial ordering selects which of two function templates is more specialized than the other by transforming
each template in turn (see next paragraph) and performing template argument deduction using the function
type. The deduction process determines whether one of the templates is more specialized than the other.
If so, the more specialized template is the one chosen by the partial ordering process. If both deductions
succeed, the partial ordering selects the more constrained template<ins> (if one exists)</ins> as<del
> described by the rules in [temp.constr.order]</del
><ins> determined below</ins
>.</p>

</blockquote><!--

--><p>Add a new paragraph to subclause 13.7.6.2 [temp.func.order] after paragraph 4:</p
><blockquote>

<p>Using the transformed function template&#x2019;s function type, perform type deduction against the other template
as described in [temp.deduct.partial].</p>
<p>[<i>Example</i>: &#x2026;]</p>

</blockquote>
<blockquote class="stdins">

<p>If deduction against the other template succeeds for both transformed templates,
constraints can be considered as follows:</p>
<ul class="dash">
<li>
If their <span class="grammar">template-parameter-list</span>s
(possibly including <span class="grammar">template-parameter</span>s invented for an abbreviated
function template ([dcl.fct]))
or function parameter lists differ in length,
neither template is more specialized than the other.</li>
<li>
Otherwise:
<ul class="dash">
<li>
If exactly one of the templates was
considered by overload resolution via a rewritten candidate with reversed order of parameters:
<ul class="dash">
<li>
If, for either template, some of the
<span class="grammar">template-parameter</span>s
are not deducible from their function parameters,
neither template is more specialized than the other.</li>
<li>
If there is either no reordering or more than one reordering of the associated <span class="grammar">template-parameter-list</span> such that the corresponding <span class="grammar">template-parameter</span>s of the <span class="grammar">template-parameter-list</span>s are equivalent and such that the function parameters that positionally correspond between the two templates are of the same type,
neither template is more specialized than the other.</li>
</ul></li>
<li>
Otherwise, if the corresponding <span class="grammar">template-parameter</span>s of the
<span class="grammar">template-parameter-list</span>s
are not equivalent ([temp.over.link]) or
if the function parameters that positionally correspond between
the two templates are not of the same type,
neither template is more specialized than the other.</li>
</ul></li>
<li>
Otherwise, if the context in which the partial ordering is done is that of a call to a conversion
function and the return types of the templates are not the same, then
neither template is more specialized than the other.</li>
<li>
Otherwise, if one template is more constrained than the other
([temp.constr.order]), the more constrained template is more specialized than the other.</li>
<li>
Otherwise, neither template is more specialized than the other.</li>
</ul>

<p>[<i>Example</i>:</p>
<pre class="example"><code>template &lt;typename&gt; constexpr bool True = true;
template &lt;typename T&gt; concept C = True&lt;T&gt;;

void f(C auto &amp;, auto &amp;) = delete;
template &lt;C Q&gt; void f(Q &amp;, C auto &amp;);

void g(struct A *ap, struct B *bp) {
  f(*ap, *bp);</code
>  <i>// OK: Can use different methods to produce template parameters</i><code>
}

template &lt;typename T, typename U&gt; struct X {};

template &lt;typename T, C U, typename V&gt;
bool operator==(X&lt;T, U&gt;, V) = delete;
template &lt;C T, C U, C V&gt;
bool operator==(T, X&lt;U, V&gt;);

void h() {
  X&lt;void *, int&gt;{} == 0; </code><i>// OK: Correspondence of [</i
><code>T</code><i>,</i> <code>U</code><i>,</i> <code>V</code><i>] and [</i><code>U</code><i>,</i> <code>V</code><i>,</i> <code>T</code><i>]</i><code>
}</code></pre>
<p>&#x2014;<i>end example</i>]</p>

</blockquote><!--

--></div>
</body></html>
