<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;P1113R0</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Date:
     </TD>
<TD>
      &#160;2018-06-08</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
     June, 2018 (Rapperswil) meeting
    </H2>
</CENTER><BR><P>
    Section references in this document reflect the section numbering
    of document
    <A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4700.pdf">WG21 N4700</A>.
   </P>
<HR><A NAME="2254"></A><H4>2254.
  
Standard-layout classes and bit-fields
</H4><B>Section: </B>12.2&#160; [class.mem]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2016-03-23




<P>According to 12.2 [class.mem] paragraph 25,</P>

<BLOCKQUOTE>

If a standard-layout class object has any non-static data members, its
address is the same as the address of its first non-static data
member. Otherwise, its address is the same as the address of its first base
class subobject (if any). [<I>Note:</I> There might therefore be unnamed
padding within a standard-layout struct object, but not at its beginning,
as necessary to achieve appropriate alignment. &#8212;<I>end note</I>]
[<I>Note:</I> The object and its first subobject are
pointer-interconvertible (6.9.2 [basic.compound],
8.2.9 [expr.static.cast]). &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>This wording does not consider the case when the first non-static
data member is a bit-field, which cannot have its address taken.</P>

<P><B>Proposed resolution, February, 2018: [SUPERSEDED]</B></P>

<P>Change 12.2 [class.mem] paragraph 25 as follows:</P>

<BLOCKQUOTE>

If a standard-layout class object has any non-static data members, its
address is the same as the address of its first non-static data
member <SPAN style="font-weight:bold;background-color:#A0FFA0">if that member is not a bit-field</SPAN>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Otherwise, its</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">Its</SPAN> address is <SPAN style="font-weight:bold;background-color:#A0FFA0">also</SPAN> the same as the address
of <SPAN style="font-weight:bold;background-color:#A0FFA0">each of</SPAN> its <SPAN style="text-decoration:line-through;background-color:#FFA0A0">first</SPAN> base class subobject<SPAN style="font-weight:bold;background-color:#A0FFA0">s</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">(if any)</SPAN>. [<I>Note:</I> There might therefore be unnamed padding
within a standard-layout struct object <SPAN style="font-weight:bold;background-color:#A0FFA0">inserted by an
implementation</SPAN>, but not at its beginning, as necessary to achieve
appropriate alignment. &#8212;<I>end note</I>] [<I>Note:</I> The object and
its first subobject are pointer-interconvertible
(6.9.2 [basic.compound], 8.2.9 [expr.static.cast]). &#8212;<I>end
note</I>]

</BLOCKQUOTE>

<P><B>Notes from the March, 2018 meeting:</B></P>

<P>It was pointed out that the definition of pointer interconvertibility
in 6.7.2 [basic.stc.thread] paragraph 4 refers to &#8220;the first base
class subobject&#8221; of the object and must also be updated to reflect
the above proposed resolution.</P>

<P><B>Proposed resolution (March, 2018):</B></P>

<OL><LI><P>Change 6.9.2 [basic.compound] bullet 4.3 as follows:</P></LI>

<BLOCKQUOTE>

<P>Two objects a and b are <I>pointer-interconvertible</I> if:</P>

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

<LI><P>one is a standard-layout class object and the other is the first
non-static data member of that object, or, if the object has no non-static
data members, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">the first</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">any</SPAN> base class subobject of
that object (12.2 [class.mem]), or</P></LI>

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

</UL>

</BLOCKQUOTE>

<LI><P>Change 12.2 [class.mem] paragraph 25 as follows:</P></LI>

<BLOCKQUOTE>

If a standard-layout class object has any non-static data members, its
address is the same as the address of its first non-static data
member <SPAN style="font-weight:bold;background-color:#A0FFA0">if that member is not a bit-field</SPAN>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Otherwise,
its</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Its</SPAN> address is <SPAN style="font-weight:bold;background-color:#A0FFA0">also</SPAN> the same as the address
of <SPAN style="font-weight:bold;background-color:#A0FFA0">each of</SPAN> its <SPAN style="text-decoration:line-through;background-color:#FFA0A0">first</SPAN> base class subobject<SPAN style="font-weight:bold;background-color:#A0FFA0">s</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">(if any)</SPAN>. [<I>Note:</I> There might therefore be unnamed padding
within a standard-layout struct object <SPAN style="font-weight:bold;background-color:#A0FFA0">inserted by an
implementation</SPAN>, but not at its beginning, as necessary to achieve
appropriate alignment. &#8212;<I>end note</I>] [<I>Note:</I> The object and
its first subobject are pointer-interconvertible
(6.9.2 [basic.compound], 8.2.9 [expr.static.cast]). &#8212;<I>end
note</I>]

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="2293"></A><H4>2293.
  
Requirements for <I>simple-template-id</I> used as a <I>class-name</I>
</H4><B>Section: </B>12&#160; [class]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>CWG
 &#160;&#160;&#160;

 <B>Date: </B>2016-06-22


<P>There is currently no requirement that a <I>simple-template-id</I>
used as a <I>class-name</I> (12 [class] paragraph 1) must
have template arguments for every template parameter that does not have
a default template argument.</P>

<P><B>Proposed resolution (March, 2018):</B></P>

<OL><LI><P>Change 6.3.1 [basic.scope.declarative] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

Every name is introduced in some portion of program text called a
declarative region, which is the largest part of the program in which that
name is <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>valid</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">valid</SPAN>, that is, in which that
name may be used as an unqualified name to refer to the same entity. In
general...

</BLOCKQUOTE>

<LI><P>Add the following as a new paragraph after 17.2 [temp.names]
paragraph 7:</P></LI>

<BLOCKQUOTE>

<P>A <I>template-id</I> that names an alias template specialization is
a <I>type-name</I>.</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>template-id</I> is <I>valid</I> if</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">there are at most as many arguments as there are parameters
or a parameter is a template parameter pack
(17.6.3 [temp.variadic]),</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">there is an argument for each non-deducible non-pack parameter that
does not have a default <I>template-argument</I>,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">each <I>template-argument</I> matches the corresponding
<I>template-parameter</I> (17.3 [temp.arg]),</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">substitution of each template argument into the following template
parameters (if any) succeeds, and</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">if the <I>template-id</I> is non-dependent, the associated
constraints are satisfied as specified in the next paragraph.</SPAN>
</P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>simple-template-id</I> shall be valid unless it names a
function template specialization
(17.9.2 [temp.deduct]). [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;class T, T::type n = 0&gt; class X;
  struct S {
    using type = int;
  };
  using T1 = X&lt;S, int, int&gt;;  //<SPAN style="font-family:Times;font-style:italic"> error: too many arguments</SPAN>
  using T2 = X&lt;&gt;;             //<SPAN style="font-family:Times;font-style:italic"> error: no default argument for first template parameter</SPAN>
  using T3 = X&lt;1&gt;;            //<SPAN style="font-family:Times;font-style:italic"> error: value </SPAN>1<SPAN style="font-family:Times;font-style:italic"> does not match type-parameter</SPAN>
  using T4 = X&lt;int&gt;;          //<SPAN style="font-family:Times;font-style:italic"> error: substitution failure for second template parameter</SPAN>
  using T5 = X&lt;S&gt;;            //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN></SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 17.9.2 [temp.deduct] paragraph 2 as follows, converting
from bullets to running text:</P></LI>

<BLOCKQUOTE>

<P>When an explicit template argument list is specified, if the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">template
arguments are not compatible with the template parameter list or do not
result in a valid function type as described below</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">given
<I>template-id</I> is invalid (17.2 [temp.names])</SPAN>, type
deduction fails.  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Specifically, the following steps are performed when
evaluating an explicitly specified template argument list with respect to a
given function template:</SPAN></P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">If the specified template arguments do not match the template
parameters in kind (i.e., type, non-type, template), or if there are more
arguments than there are parameters and no parameter is a template
parameter pack, or if there is not an argument for each non-pack parameter,
type deduction fails.</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">If any non-type argument does not match the type of the
corresponding non-type template parameter, and is not convertible to the
type of the corresponding non-type parameter as specified in
17.3.2 [temp.arg.nontype], type deduction fails.</SPAN></P></LI>

<LI><P>The specified template argument values are substituted for the
corresponding template parameters as specified below.</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="2294"></A><H4>2294.
  
Dependent <TT>auto</TT> static data members
</H4><B>Section: </B>17.7.2.2&#160; [temp.dep.expr]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2016-06-22


<P>The list of type-dependent <I>id-expression</I>s in
17.7.2.2 [temp.dep.expr] paragraph 3 should include the case when a
static data member is declared with the <TT>auto</TT> type specifier and
the initializer is dependent.</P>

<P><B>Proposed resolution, March, 2018:</B></P>

<P>Add the following as a new bullet after 17.7.2.2 [temp.dep.expr]
bullet 3.2:</P>

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

<LI><P>an <I>identifier</I> associated by name lookup with a
non-type <I>template-parameter</I> declared with a type that contains a
placeholder type (10.1.7.4 [dcl.spec.auto]),</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">an <I>identifier</I> associated by name lookup with a variable
declared with a type that contains a placeholder type
(10.1.7.4 [dcl.spec.auto]) where the initializer is
type-dependent,</SPAN></P></LI>

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

</UL>

<BR><BR><HR><A NAME="2321"></A><H4>2321.
  
Conditional operator and cv-qualified class prvalues
</H4><B>Section: </B>8.16&#160; [expr.cond]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2016-09-06




<P>The following example is ill-formed:</P>

<PRE>
  struct A {}; 
  struct B : A {}; 
  using T = const B; 
  A a = true ? A() : T();
</PRE>

<P>We don't convert from <TT>A</TT> to <TT>T</TT> because we can't form an
implicit conversion sequence. We don't convert from <TT>T</TT>
to <TT>A</TT> because <TT>T</TT> is more cv-qualified (even though we could
form an implicit conversion sequence).  It would seem reasonable to accept
this case; it seems that we should only be using cv-qualifiers as a
tie-breaker if the class types are otherwise the same.</P>

<P><B>Proposed resolution (March, 2018):</B></P>

<P>Change 8.16 [expr.cond] bullet 4.3 as follows:</P>

<BLOCKQUOTE>

<P>...Attempts are made to form an implicit conversion sequence from an
operand expression <TT>E1</TT> of type <TT>T1</TT> to a target type related
to the type <TT>T2</TT> of the operand expression <TT>E2</TT> as
follows:</P>

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

<LI><P>If <TT>E2</TT> is a prvalue or if neither of the conversion
sequences above can be formed and at least one of the operands has
(possibly cv-qualified) class type:</P></LI>

<UL><LI><P>if <TT>T1</TT> and <TT>T2</TT> are the same class type (ignoring
cv-qualification)<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, or one is a base class of the other,</SPAN>
and <TT>T2</TT> is at least as cv-qualified as <TT>T1</TT> , the target
type is <TT>T2</TT>,</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">otherwise, if <TT>T2</TT> is a base class of <TT>T1</TT>,
the target type is <I>cv1</I> <TT>T2</TT>, where <I>cv1</I> denotes the
cv-qualifiers of <TT>T1</TT>,</SPAN></P></LI>

<LI><P>otherwise, the target type is the type that <TT>E2</TT> would have
after applying the lvalue-to-rvalue (7.1 [conv.lval]),
array-to-pointer (7.2 [conv.array]), and function-to-pointer
(7.3 [conv.func]) standard conversions.</P></LI>

</UL>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="2322"></A><H4>2322.
  
Substitution failure and lexical order
</H4><B>Section: </B>17.9.2&#160; [temp.deduct]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Xiang Fan
 &#160;&#160;&#160;

 <B>Date: </B>2016-09-06




<P>According to 17.9.2 [temp.deduct] paragraph 7,</P>

<BLOCKQUOTE>

The substitution occurs in all types and expressions that are used in the
function type and in template parameter declarations. The expressions
include not only constant expressions such as those that appear in array
bounds or as nontype template arguments but also general expressions (i.e.,
non-constant expressions) inside <TT>sizeof</TT>, <TT>decltype</TT>, and
other contexts that allow non-constant expressions. The substitution
proceeds in lexical order and stops when a condition that causes deduction
to fail is encountered.

</BLOCKQUOTE>

<P>However, the same type can be represented in different lexical orders.
For example, there is implementation variance on the following example,
presumably because of preferring different declarations:</P>

<PRE>
  template &lt;class T&gt; struct A { using X = typename T::X; }; 

  template &lt;class T&gt; typename T::X f(typename A&lt;T&gt;::X); 
  template &lt;class T&gt; auto f(typename A&lt;T&gt;::X) -&gt; typename T::X; 
  template &lt;class T&gt; void f(...) { } 

  void h() { 
    f&lt;int&gt;(0); 
  } 
</PRE>

<P><B>Proposed resolution, March, 2018:</B></P>

<P>Change 17.9.2 [temp.deduct] paragraph 7 as follows:</P>

<BLOCKQUOTE>

<P>The substitution occurs in all types and expressions that are used in
the function type and in template parameter declarations. The expressions
include not only constant expressions such as those that appear in array
bounds or as nontype template arguments but also general expressions (i.e.,
non-constant expressions) inside sizeof, decltype, and other contexts that
allow non-constant expressions. The substitution proceeds in lexical order
and stops when a condition that causes deduction to fail is
encountered. <SPAN style="font-weight:bold;background-color:#A0FFA0">If substitution into different declarations of the same
function template would cause template instantiations to occur in a
different order or not at all, the program is ill-formed; no diagnostic
required.</SPAN> [<I>Note:</I> The equivalent substitution in exception
specifications is done only when the <I>noexcept-specifier</I> is
instantiated, at which point a program is ill-formed if the substitution
results in an invalid type or expression. &#8212;<I>end note</I>]
[<I>Example:</I></P>

<PRE>
  template &lt;class T&gt; struct A { using X = typename T::X; };
  template &lt;class T&gt; typename T::X f(typename A&lt;T&gt;::X);
  template &lt;class T&gt; void f(...) { }
  template &lt;class T&gt; auto g(typename A&lt;T&gt;::X) -&gt; typename T::X;
  template &lt;class T&gt; void g(...) { }
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template &lt;class T&gt; typename T::X h(typename A&lt;T&gt;::X);
  template &lt;class T&gt; auto h(typename A&lt;T&gt;::X) -&gt; typename T::X; //<SPAN style="font-family:Times;font-style:italic"> redeclaration</SPAN>
  template &lt;class T&gt; void h(...) { }</SPAN>

  void <SPAN style="text-decoration:line-through;background-color:#FFA0A0">h</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">x</SPAN>() {
    f&lt;int&gt;(0);    //<SPAN style="font-family:Times;font-style:italic"> OK, substituting return type causes deduction to fail</SPAN>
    g&lt;int&gt;(0);    //<SPAN style="font-family:Times;font-style:italic"> error, substituting parameter type instantiates </SPAN>A&lt;int&gt;
<SPAN style="font-weight:bold;background-color:#A0FFA0">    h&lt;int&gt;(0);    //<SPAN style="font-family:Times;font-style:italic"> ill-formed, no diagnostic required</SPAN></SPAN>
  }
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="2339"></A><H4>2339.
  
Underspecified template arguments in structured bindings
</H4><B>Section: </B>11.5&#160; [dcl.struct.bind]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2017-03-29


<P>According to 11.5 [dcl.struct.bind] paragraph 3,</P>

<BLOCKQUOTE>

Otherwise, if
the <I>qualified-id</I> <TT>std::tuple_size&lt;E&gt;</TT> names a
complete type, the
expression <TT>std::tuple_size&lt;E&gt;::value</TT> shall be a
well-formed integral constant expression and the number of
elements in the <I>identifier-list</I> shall be equal to the
value of that expression. The <I>unqualified-id</I> <TT>get</TT>
is looked up in the scope of <TT>E</TT> by class member access
lookup (6.4.5 [basic.lookup.classref]), and if that finds at least
one declaration, the initializer is <TT>e.get&lt;i&gt;()</TT>.
Otherwise, the initializer is <TT>get&lt;i&gt;(e)</TT>,
where <TT>get</TT> is looked up in the associated namespaces
(6.4.2 [basic.lookup.argdep]). In either
case, <TT>get&lt;i&gt;</TT> is interpreted as
a <I>template-id</I>.

</BLOCKQUOTE>

<P>It is not clear what <TT>i</TT> is in this description, and in
particular, its type is not specified.</P>

<P><B>Proposed resolution, March, 2018:</B></P>

<P>Change 11.5 [dcl.struct.bind] paragraph 3 as follows:</P>

<BLOCKQUOTE>

Otherwise, if the <I>qualified-id</I> <TT>std::tuple_size&lt;E&gt;</TT>
names a complete type, the
expression <TT>std::tuple_size&lt;E&gt;::value</TT> shall be a well-formed
integral constant expression and the number of elements in
the <I>identifier-list</I> shall be equal to the value of that
expression. <SPAN style="font-weight:bold;background-color:#A0FFA0">Let <TT>i</TT> be an index prvalue of type
<TT>std::size_t</TT> corresponding to <TT>v</TT><I><SUB>i</SUB></I>.</SPAN>
The <I>unqualified-id</I> <TT>get</TT> is looked up in the scope
of <TT>E</TT> by class member access lookup (6.4.5 [basic.lookup.classref]),
and if that finds at least one declaration, the initializer
is <TT>e.get&lt;i&gt;()</TT>.  Otherwise, the initializer
is <TT>get&lt;i&gt;(e)</TT>, where <TT>get</TT> is looked up in the
associated namespaces (6.4.2 [basic.lookup.argdep]). In either case,
<TT>get&lt;i&gt;</TT> is interpreted as a <I>template-id</I>. [<I>Note:</I>
Ordinary unqualified lookup...

</BLOCKQUOTE>

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