<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    CWG Issue 2445</TITLE>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<STYLE TYPE="text/css">
  INS { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .INS { text-decoration:none; background-color:#D0FFD0 }
  DEL { text-decoration:line-through; background-color:#FFA0A0 }
  .DEL { text-decoration:line-through; background-color: #FFD0D0 }
  @media (prefers-color-scheme: dark) {
    HTML { background-color:#202020; color:#f0f0f0; }
    A { color:#5bc0ff; }
    A:visited { color:#c6a8ff; }
    A:hover, a:focus { color:#afd7ff; }
    INS { background-color:#033a16; color:#aff5b4; }
    .INS { background-color: #033a16; }
    DEL { background-color:#67060c; color:#ffdcd7; }
    .DEL { background-color:#67060c; }
  }
  SPAN.cmnt { font-family:Times; font-style:italic }
</STYLE>
</HEAD>
<BODY>
<P><EM>This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21
  Core Issues List revision 118b.
  See http://www.open-std.org/jtc1/sc22/wg21/ for the official
  list.</EM></P>
<P>2025-09-28</P>
<HR>
<A NAME="2445"></A><H4>2445.
  
Partial ordering with rewritten candidates
</H4>
<B>Section: </B>13.7.7.3&#160; [<A href="https://wg21.link/temp.func.order">temp.func.order</A>]
 &#160;&#160;&#160;

 <B>Status: </B>C++20
 &#160;&#160;&#160;

 <B>Submitter: </B>Hubert Tong
 &#160;&#160;&#160;

 <B>Date: </B>2020-01-29<BR>


<P>[Accepted at the February, 2020 (Prague) meeting.]</P>



<P>The tiebreaker based on partial ordering of function templates should
presumably operate upon rewritten candidates based on their parameter lists
for the purpose of overload resolution (12.2.2 [<A href="https://wg21.link/over.match.funcs">over.match.funcs</A>]) without
substitution of template arguments instead of the function parameter lists
of the templates themselves.</P>

<P>It is observed, however, that neither GCC nor Clang performs partial
ordering in the manner described above. In the following case, considering
the templates with the reordering should yield 1a as being more specialized
than 2; however, the wording is not especially clear about this and both
GCC and Clang seems to fall past the partial ordering tiebreaker to pick 2
for the case as-is. If 1b is introduced, then it is more specialized than 2
in either ordering, and it is chosen by both GCC and Clang.</P>

<PRE>
  template &lt;typename&gt; constexpr bool F = false;
  template &lt;typename T&gt; struct A { };

  template &lt;typename T, typename U&gt;
  // bool operator==(A&lt;T&gt;, A&lt;U *&gt;);       //<SPAN CLASS="cmnt"> 1b</SPAN>
  bool operator==(T, A&lt;U *&gt;);             //<SPAN CLASS="cmnt"> 1a</SPAN>

  template &lt;typename T, typename U&gt;
  bool operator!=(A&lt;T&gt;, U) {              //<SPAN CLASS="cmnt"> 2</SPAN>
   static_assert(F&lt;T&gt;, "Isn't this less specialized?");
   return false;
  }

  bool f(A&lt;int&gt; ax, A&lt;int *&gt; ay) { return ay != ax; }
</PRE>

<P><B>Proposed resolution (February, 2020):</B></P>

<P>Change 13.7.7.3 [<A href="https://wg21.link/temp.func.order#3">temp.func.order</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>To produce the transformed template, for each type,
non-type, or template template parameter (including template
parameter packs (13.7.4 [<A href="https://wg21.link/temp.variadic">temp.variadic</A>]) thereof)
synthesize a unique type, value, or class template
respectively and substitute it for each occurrence of that
parameter in the function type of the
template. [<I>Note:</I> The type replacing the placeholder
in the type of the value synthesized for a non-type template
parameter is also a unique synthesized type. &#8212;<I>end
note</I>] <DEL>If only one of the</DEL> <INS>Each</INS>
function <DEL>templates</DEL> <INS>template</INS>
<I>M</I> <INS>that</INS> is a member function<DEL>, and that
function is a non-static member of some
class <I>A</I>, <I>M</I></DEL> is considered to have a new
first parameter <INS>of type X(<I>M</I>), described
below,</INS> inserted in its function parameter
list. <DEL>Given <I>cv</I> as the</DEL>
<INS>If exactly one of the function templates was considered
by overload resolution via a rewritten candidate
(12.2.2.3 [<A href="https://wg21.link/over.match.oper">over.match.oper</A>]) with a reversed order of
parameters, then the order of the function parameters in its
transformed template is reversed. For a function
template <I>M</I> with</INS> cv-qualifiers <DEL>of M (if
any), the new parameter</DEL> <INS><I>cv</I> that is a
member of a class <I>A</I>:</INS>
</P>

<UL>

<LI><P>
<INS>The type X(<I>M</I>)</INS> is <DEL>of type</DEL>
&#8220;rvalue reference to <I>cv A</I>&#8221; if the
optional <I>ref-qualifier</I> of <I>M</I>
is <TT>&amp;&amp;</TT> or if <I>M</I> has
no <I>ref-qualifier</I> and the <DEL>first</DEL>
<INS>positionally corresponding</INS> parameter of the other
<INS>transformed</INS> template has rvalue reference
type<INS>; if this determination depends recursively upon
whether X(<I>M</I>) is an rvalue reference type, it is not
considered to have rvalue reference type</INS>.</P></LI>

<LI><P>Otherwise, <DEL>the new parameter</DEL>
<INS>X(<I>M</I>)</INS> is <DEL>of type</DEL> &#8220;lvalue
reference to <I>cv A</I>&#8221;.</P></LI>

</UL>

<P>[<I>Note:</I> This allows...</P>

</BLOCKQUOTE>

<BR><BR>
</BODY>
</HTML>
