<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    Core "ready" Issues
   </TITLE>
</HEAD>
<BODY>
<TABLE ALIGN="RIGHT" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD ALIGN="RIGHT">
      Document number:
     </TD>
<TD>
       &#160;P2108R0</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Date:
     </TD>
<TD>
      &#160;2020-02-14</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Project:
     </TD>
<TD>
      &#160;Programming Language C++
     </TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Reference:
     </TD>
<TD>
      &#160;ISO/IEC IS 14882:2017
     </TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Reply to:
     </TD>
<TD>
      &#160;William M. Miller
     </TD>
</TR>
<TR>
<TD></TD>
<TD>
      &#160;Edison Design Group, Inc.
     </TD>
</TR>
<TR>
<TD></TD>
<TD>
      &#160;<A HREF="mailto://wmm@edg.com">wmm@edg.com</A></TD>
</TR>
</TABLE><BR CLEAR="ALL"><BR><CENTER>
<H2>
     Core Language Working Group "ready" Issues
     for the
     February, 2020 (Prague) meeting
    </H2>
</CENTER><BR><P>
    References in this document reflect the section and paragraph
    numbering of document
    <A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4849.pdf">WG21 N4849</A>.
   </P>
<HR><A NAME="2053"></A><H4>2053.
  
<TT>auto</TT> in non-generic lambdas
</H4><B>Section: </B>9.2.8.5&#160; [dcl.spec.auto]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Faisal Vali
 &#160;&#160;&#160;

 <B>Date: </B>2014-12-07




<P>According to 9.2.8.5 [dcl.spec.auto] paragraph 3,</P>

<BLOCKQUOTE>

If the <TT>auto</TT> <I>type-specifier</I> appears as one of
the <I>decl-specifier</I>s in the <I>decl-specifier-seq</I>
of a <I>parameter-declaration</I> of
a <I>lambda-expression</I>, the lambda is a <I>generic lambda</I>
(7.5.5 [expr.prim.lambda]).

</BLOCKQUOTE>

<P>and 7.5.5 [expr.prim.lambda] paragraph 5 says,

<BLOCKQUOTE>

For a generic lambda, the closure type has a public inline
function call operator member template
(13.7.2 [temp.mem])
whose <I>template-parameter-list</I> consists of one
invented type <I>template-parameter</I> for each occurrence
of <TT>auto</TT> in the lambda's <I>parameter-declaration-clause</I>,
in order of appearance.

</BLOCKQUOTE></P>

<P>However, an <TT>auto</TT> that signals a
<I>trailing-return-type</I> should be excluded from these
descriptions.</P>

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

<P>This issue is resolved by the resolution of
issue 2447.</P>

<BR><BR><HR><A NAME="2445"></A><H4>2445.
  
Partial ordering with rewritten candidates
</H4><B>Section: </B>13.7.6.2&#160; [temp.func.order]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

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

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




<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.4.1 [over.match.funcs]) 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 style="font-family:Times;font-style:italic"> 1b</SPAN>
  bool operator==(T, A&lt;U *&gt;);             //<SPAN style="font-family:Times;font-style:italic"> 1a</SPAN>

  template &lt;typename T, typename U&gt;
  bool operator!=(A&lt;T&gt;, U) {              //<SPAN style="font-family:Times;font-style:italic"> 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.6.2 [temp.func.order] 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.3 [temp.variadic]) 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>] <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If only one of the</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Each</SPAN>
function <SPAN style="text-decoration:line-through;background-color:#FFA0A0">templates</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">template</SPAN>
<I>M</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">that</SPAN> is a member function<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, and that
function is a non-static member of some
class <I>A</I>, <I>M</I></SPAN> is considered to have a new
first parameter <SPAN style="font-weight:bold;background-color:#A0FFA0">of type X(<I>M</I>), described
below,</SPAN> inserted in its function parameter
list. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Given <I>cv</I> as the</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">If exactly one of the function templates was considered
by overload resolution via a rewritten candidate
(12.4.1.2 [over.match.oper]) 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</SPAN> cv-qualifiers <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of M (if
any), the new parameter</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>cv</I> that is a
member of a class <I>A</I>:</SPAN></P>

<UL>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">The type X(<I>M</I>)</SPAN> is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of type</SPAN>
&#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 <SPAN style="text-decoration:line-through;background-color:#FFA0A0">first</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">positionally corresponding</SPAN> parameter of the other
<SPAN style="font-weight:bold;background-color:#A0FFA0">transformed</SPAN> template has rvalue reference
type<SPAN style="font-weight:bold;background-color:#A0FFA0">; 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</SPAN>.</P></LI>

<LI><P>Otherwise, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the new parameter</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">X(<I>M</I>)</SPAN> is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">of type</SPAN> &#8220;lvalue
reference to <I>cv A</I>&#8221;.</P></LI>

</UL>

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

</BLOCKQUOTE>

<BR><BR><HR><A NAME="2446"></A><H4>2446.
  
Questionable type-dependency of <I>concept-id</I>s
</H4><B>Section: </B>13.8.2.2&#160; [temp.dep.expr]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

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

 <B>Date: </B>2019-02-03




<P>The rules for type-dependency do not appear to take the
<TT>bool</TT> type associated with <I>concept-id</I>s into
account. For example:</P>

<PRE>
  template &lt;typename T&gt; concept C = true;
  template &lt;typename T&gt; struct A;
  template &lt;&gt; struct A&lt;bool&gt; { using type = bool; };

  template &lt;typename T&gt;
  void f(A&lt;decltype(C&lt;T&gt;)&gt;::type); //<SPAN style="font-family:Times;font-style:italic"> error: needs </SPAN>typename<SPAN style="font-family:Times;font-style:italic"> to avoid vexing parse</SPAN>
</PRE>

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

<OL><LI><P>Change 13.8.2.2 [temp.dep.expr] paragraph 3
as follows:</P></LI>

<BLOCKQUOTE>

<P>An <I>id-expression</I> is type-dependent if <SPAN style="font-weight:bold;background-color:#A0FFA0">it is
not a <I>concept-id</I> and</SPAN> it contains</P>

<UL><LI><P>...</P></LI></UL>

</BLOCKQUOTE>

<LI><P>Change 13.8.2.3 [temp.dep.constexpr] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<P>An <I>id-expression</I> is value-dependent if:</P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">it is a <I>concept-id</I> and any of its
arguments are dependent,</SPAN></P></LI>

<LI><P>it is type-dependent,</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="2447"></A><H4>2447.
  
Unintended description of abbreviated function templates
</H4><B>Section: </B>9.2.8.5&#160; [dcl.spec.auto]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

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

 <B>Date: </B>2019-10-15




<P>The current wording for abbreviated function
templates could lead to the incorrect conclusion that
<TT>f</TT> and <TT>g</TT> in the example below are well-formed
abbreviated function templates. The <TT>g</TT> case is the
abbreviated function template analog of
issue 2053 regarding generic
lambdas.</P>

<P>9.2.8.5 [dcl.spec.auto] paragraph 4 clearly disallows
the <TT>ap</TT> case. The inconsistency between the paragraph
2 wording for abbreviated function templates and the paragraph
4 wording is unintentional.</P>

<PRE>
  template &lt;typename&gt; struct A;
  void f(A&lt;auto&gt; x);
  void g(auto f() -&gt; int);
  A&lt;auto&gt; *ap = static_cast&lt;A&lt;int&gt; *&gt;(0);
</PRE>

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

<OL><LI><P>Change 9.2.8.5 [dcl.spec.auto] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

A <I>placeholder-type-specifier</I> of the
form <I>type-constraint<SUB>opt</SUB></I> <TT>auto</TT> can
be used <SPAN style="text-decoration:line-through;background-color:#FFA0A0">in</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">as a <I>decl-specifier</I>
of</SPAN> the <I>decl-specifier-seq</I> of
a <I>parameter-declaration</I> of a function declaration
or <I>lambda-expression</I> and<SPAN style="font-weight:bold;background-color:#A0FFA0">, if it is not
the <TT>auto</TT> <I>type-specifier</I> introducing
a <I>trailing-return-type</I> (see below), is a <I>generic
parameter type placeholder</I> of the function declaration
or <I>lambda-expression</I>. [<I>Note:</I> Having a generic
parameter type placeholder</SPAN> signifies that the function
is an abbreviated function template
(9.3.3.5 [dcl.fct]) or the lambda is a generic
lambda (7.5.5 [expr.prim.lambda]). <SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end
note</I>]</SPAN>

</BLOCKQUOTE>

<LI><P>Change 9.3.3.5 [dcl.fct] paragraph 18 as follows:</P></LI>

<BLOCKQUOTE>

An <I>abbreviated function template</I> is a function
declaration <SPAN style="text-decoration:line-through;background-color:#FFA0A0">whose <I>parameter-type-list</I> includes</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">that has</SPAN> one or more <SPAN style="font-weight:bold;background-color:#A0FFA0">generic parameter
type</SPAN> placeholders (9.2.8.5 [dcl.spec.auto]). An
abbreviated function template is equivalent to a function
template (13.7.6.1 [temp.over.link])
whose <I>template-parameter-list</I> includes one invented
type <I>template-parameter</I> for each <SPAN style="text-decoration:line-through;background-color:#FFA0A0">occurrence of a</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">generic parameter type</SPAN> placeholder <SPAN style="text-decoration:line-through;background-color:#FFA0A0">type in
the <I>decl-specifier-seq</I> of
a <I>parameter-declaration</I> in the
function's <I>parameter-type-list</I></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">of the function declaration</SPAN>, in order of
appearance.  For a <I>placeholder-type-specifier</I> of the
form...

</BLOCKQUOTE>

<LI><P>Change 7.5.5 [expr.prim.lambda] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

A lambda is a <i>generic lambda</i> if <SPAN style="text-decoration:line-through;background-color:#FFA0A0">there is
a <I>decl-specifier</I> that is
a <I>placeholder-type-specifier</I> in
the <I>decl-specifier-seq</I> of
a <I>parameter-declaration</I> of</SPAN>
the <I>lambda-expression</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">has any generic parameter
type placeholders (9.2.8.5 [dcl.spec.auto])</SPAN>, or
if the lambda has a <I>template-parameter-list</I>.
[<I>Example:</I>...

</BLOCKQUOTE>

</OL>

<P>This resolution also resolves issue 2053.</P>

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