<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    Core "tentatively ready" Issues
   </TITLE>
</HEAD>
<BODY>
<TABLE ALIGN="RIGHT" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD ALIGN="RIGHT">
      Document number:
     </TD>
<TD>
       &#160;P0711R0</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Date:
     </TD>
<TD>
      &#160;2017-06-19</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:2014
     </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 "tentatively ready" Issues
     for the
     July, 2017 (Toronto) 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/n4659.pdf">WG21 N4659</A>.
   </P>
<HR><A NAME="1523"></A><H4>1523.
  
Point of declaration in range-based <TT>for</TT>
</H4><B>Section: </B>9.5.4&#160; [stmt.ranged]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2012-07-16


<P>According to the general rule for declarations in 6.3.2 [basic.scope.pdecl]
paragraph 1,</P>

<BLOCKQUOTE>

The <I>point of declaration</I> for a name is immediately after its
complete declarator (Clause 11 [dcl.decl]) and before its
<I>initializer</I> (if any), except as noted below.

</BLOCKQUOTE>

<P>However, the rewritten expansion of the range-based <TT>for</TT>
statement in 9.5.4 [stmt.ranged] paragraph 1 contradicts
this general rule, so that the index variable is not visible in the
<I>range-init</I>:</P>

<PRE>
  for (int i : {i}) ;   //<SPAN style="font-family:Times;font-style:italic"> error: </SPAN>i<SPAN style="font-family:Times;font-style:italic"> not in scope</SPAN>
</PRE>

<P>(See also issue 1498 for another
question regarding the rewritten form of the range-based <TT>for</TT>.)</P>

<P><B>Notes from the October, 2012 meeting:</B></P>

<P>EWG is discussing issue 900 and the
outcome of that discussion should be taken into consideration in
addressing this issue.</P>

<P><B>Notes from the April, 2013 meeting:</B></P>

<P>The approach favored by CWG for resolving this issue is to change
the point of declaration of the variable in the <I>for-range-declaration</I>
to be after the <TT>)</TT>.</P>

<P><B>Proposed resolution (May, 2017):</B></P>

<P>Add the following as a new pareagraph following
6.3.2 [basic.scope.pdecl] paragraph 9:</P>

<BLOCKQUOTE>

<P>The point of declaration for a function-local predefined variable
(11.4 [dcl.fct.def]) is immediately before
the <I>function-body</I> of a function definition.</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The point of declaration for the variable or the structured
bindings declared in the <I>for-range-declaration</I> of a
range-based <TT>for</TT> statement (9.5.4 [stmt.ranged]) is
immediately after the <I>for-range-initializer</I>.</SPAN></P>

<P>The point of declaration for a template parameter...</P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1704"></A><H4>1704.
  
Type checking in explicit instantiation of variable templates
</H4><B>Section: </B>17.7.2&#160; [temp.explicit]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2013-06-20




<P>It is not clear whether the following is well-formed or not:</P>

<PRE>
  template&lt;typename T&gt; int arr[sizeof(T)] = {};
  template int arr&lt;int&gt;[];
</PRE>

<P>Are we supposed to instantiate the specialization and treat the explicit
instantiation declaration as if it were a redeclaration (in which case the
omitted array bound would presumably be OK), or is the type of the explicit
instantiation declaration required to exactly match the type that the
instantiated specialization has (in which case the omitted bound would
presumably not be OK)? Or something else?</P>

<P>(See also issue 1728.)</P>

<P><B>Proposed resolution (May, 2017):</B></P>

<OL><LI><P>Change 17.7.2 [temp.explicit] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

If the explicit instantiation is for a class or member class,
the <I>elaborated-type-specifier</I> in the <I>declaration</I>
shall include a <I>simple-template-id</I><SPAN style="font-weight:bold;background-color:#A0FFA0">; otherwise,
the <I>declaration</I> shall be a <I>simple-declaration</I>
whose <I>init-declarator-list</I> comprises a single
<I>init-declarator</I> that does not have
an <I>initializer</I></SPAN>. If the explicit instantiation is for
a function or member function, the <I>unqualified-id</I> in the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>declaration</I></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>declarator</I></SPAN> shall
be either a <I>template-id</I> or, where all template arguments
can be deduced, a <I>template-name</I>
or <I>operator-function-id</I>. [<I>Note:</I> The declaration may
declare a <I>qualified-id</I>, in which case
the <I>unqualified-id</I> of the <I>qualified-id</I> must be
a <I>template-id</I>. &#8212;<I>end note</I>] If the explicit
instantiation is for a member function, a member class or a
static data member of a class template specialization, the name
of the class template specialization in the <I>qualified-id</I>
for the member name shall be a <I>simple-template-id</I>. If the
explicit instantiation is for a variable <SPAN style="font-weight:bold;background-color:#A0FFA0">template
specialization</SPAN>, the <I>unqualified-id</I> in the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">declaration</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declarator</SPAN> shall be
a <I><SPAN style="font-weight:bold;background-color:#A0FFA0">simple-</SPAN>template-id</I>. An explicit instantiation
shall appear in an enclosing namespace of its template. If the
name declared in the explicit instantiation is an unqualified
name, the explicit instantiation shall appear in the namespace
where its template is declared or, if that namespace is inline
(10.3.1 [namespace.def]), any namespace from its enclosing
namespace set. [<I>Note:</I>...

</BLOCKQUOTE>

<LI><P>Add the following as a new paragraph following
17.7.2 [temp.explicit] paragraph 4:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The <I>declaration</I> in an <I>explicit-instantiation</I>
and the <I>declaration</I> produced by the corresponding
substitution into the templated function, variable, or class are
two declarations of the same entity. [<I>Note:</I> These declarations
are required to have matching types as specified in
6.5 [basic.link], except as specified in
18.4 [except.spec]. [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">   template&lt;typename T&gt; T var = {};
   template float var&lt;float&gt;;   //<SPAN style="font-family:Times;font-style:italic"> OK, instantiated variable has type</SPAN> float
   template int var&lt;int[16]&gt;[]; //<SPAN style="font-family:Times;font-style:italic"> OK, absence of major array bound is permitted</SPAN>
   template int *var&lt;int&gt;;      //<SPAN style="font-family:Times;font-style:italic"> error: instantiated variable has type</SPAN> int

   template&lt;typename T&gt; auto av = T();
   template int av&lt;int&gt;;        //<SPAN style="font-family:Times;font-style:italic"> OK, variable with type </SPAN>int<SPAN style="font-family:Times;font-style:italic"> can be redeclared with type</SPAN> auto

   template&lt;typename T&gt; auto f() {}
   template void f&lt;int&gt;();      //<SPAN style="font-family:Times;font-style:italic"> error: function with deduced return type redeclared with non-deduced return type (10.1.7.4 [dcl.spec.auto])</SPAN></SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>] &#8212;<I>end note</I>] Despite its
syntactic form, the <I>declaration</I> in an <I>explicit-instantiation</I>
for a variable is not itself a definition and does not conflict with the
definition instantiated by an explicit instantiation definition for
that variable.</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 17.7.2 [temp.explicit] paragraph 10 as follows:</P>

<BLOCKQUOTE>

Except for inline functions and variables, declarations with
types deduced from their initializer or return value
(10.1.7.4 [dcl.spec.auto]), <TT>const</TT> variables of
literal types, variables of reference types, and class template
specializations, explicit instantiation declarations have the
effect of suppressing the implicit instantiation of
the <SPAN style="font-weight:bold;background-color:#A0FFA0">definition of the</SPAN> entity to which they
refer. [<I>Note:</I>...

</BLOCKQUOTE>
</LI>

</OL>

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

<BR><BR><HR><A NAME="1728"></A><H4>1728.
  
Type of an explicit instantiation of a variable template
</H4><B>Section: </B>17.7.2&#160; [temp.explicit]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Larisse Voufo
 &#160;&#160;&#160;

 <B>Date: </B>2013-08-05




<P>It is not clear to what extent the type in an explicit instantiation
must match that of a variable template.  For example:</P>

<PRE>
  template&lt;typename T&gt; T var = T();
  template float var&lt;float&gt;;   //<SPAN style="font-family:Times;font-style:italic"> #1.</SPAN>
  template int* var&lt;int&gt;;      //<SPAN style="font-family:Times;font-style:italic"> #2.</SPAN>
  template auto var&lt;char&gt;;     //<SPAN style="font-family:Times;font-style:italic"> #3.</SPAN>
</PRE>

<P>(See also issue 1704.)</P>

<P><B>Proposed resolution (May, 2017):</B></P>

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

<BR><BR><HR><A NAME="1836"></A><H4>1836.
  
Use of class type being defined in <I>trailing-return-type</I>
</H4><B>Section: </B>_N4567_.5.1.1&#160; [expr.prim.general]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>2014-01-17


<P>According to _N4567_.5.1.1 [expr.prim.general] paragraph 3,</P>

<BLOCKQUOTE>

Unlike the object expression in other
contexts, <TT>*this</TT> is not required to be of complete
type for purposes of class member access
(8.2.5 [expr.ref]) outside the member function
body.

</BLOCKQUOTE>

<P>Is this special treatment of member access expressions intended
to apply only to <TT>*this</TT>, or does it apply to other ways of
specifying the class being defined in the object expression?  For
example,</P>

<PRE>
  struct S {
    int i;
    auto f1() -&gt; decltype((*this).i);      //<SPAN style="font-family:Times;font-style:italic"> okay</SPAN>
    auto f2(S&amp; This) -&gt; decltype(This.i);  //<SPAN style="font-family:Times;font-style:italic"> okay?</SPAN>
    auto f3() -&gt; decltype(((S*)0)-&gt;i);     //<SPAN style="font-family:Times;font-style:italic"> okay?</SPAN>
  };
</PRE>

<P>There is implementation divergence on this question.</P>

<P>If the intent is to allow object expressions other than
<TT>*this</TT> to have the current class type, this specification
should be moved from _N4567_.5.1.1 [expr.prim.general] to
8.2.5 [expr.ref] paragraph 2, which is where the general
requirement for complete object expression types is found.</P>

<P>On a related point, the note immediately following the above-cited
passage is not quite correct:</P>

<BLOCKQUOTE>

[<I>Note:</I> only class members declared prior to the
declaration are visible. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>This does not apply when the member is a &#8220;member of an
unknown specialization,&#8221; per 17.6.2.1 [temp.dep.type]
paragraph 5 bullet 3 sub-bullet 1; for example,</P>

<PRE>
  template&lt;typename T&gt; struct S : T {
    auto f() -&gt; decltype(this-&gt;x);
  };
</PRE>

<P>Here <TT>x</TT> is presumed to be a member of the dependent base
<TT>T</TT> and is not &#8220;declared prior to the declaration&#8221;
that refers to it.</P>

<P><B>Proposed resolution (May, 2017):</B></P>

<OL><LI><P>Change 8.1.2 [expr.prim.this] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Unlike the object expression in other contexts, <TT>*this</TT>
is not required to be of complete type for purposes of class
member access (8.2.5 [expr.ref]) outside the member
function body. [<I>Note:</I> Only class members declared prior to
the declaration are visible. &#8212;<I>end note</I>]</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">
[<I>Note:</I> In a <I>trailing-return-type</I>, the class being
defined is not required to be complete for purposes of class member
access (8.2.5 [expr.ref]). Class members declared later
are not visible.</SPAN> [<I>Example:</I></P>

<PRE>
  struct A {
    char g();
    template&lt;class T&gt; auto f(T t) -&gt; decltype(t + g())
    { return t + g(); }
  };
  template auto A::f(int t) -&gt; decltype(t + g());
</PRE>

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

</BLOCKQUOTE>

<LI><P>Change 8.2.5 [expr.ref] paragraph 2 as follows,
splitting the paragraph into two paragraphs as indicated:</P></LI>

<BLOCKQUOTE>

<P>For the first option (dot) the first expression shall be a
glvalue having <SPAN style="text-decoration:line-through;background-color:#FFA0A0">complete</SPAN> class type. For the second
option (arrow) the first expression shall be a prvalue having
pointer to <SPAN style="text-decoration:line-through;background-color:#FFA0A0">complete</SPAN> class type. <SPAN style="font-weight:bold;background-color:#A0FFA0">In both cases,
the class type shall be complete unless the class member access
appears in the definition of that class. [<I>Note:</I> If the
class is incomplete, lookup in the complete class type is
required to refer to the same declaration
(6.3.7 [basic.scope.class]). &#8212;<I>end note</I>]</SPAN></P>

<P>The expression <TT>E1-&gt;E2</TT> is converted to the
equivalent form <TT>(*(E1)).E2</TT>; the remainder...</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="2273"></A><H4>2273.
  
Inheriting constructors vs implicit default constructor
</H4><B>Section: </B>15.1&#160; [class.ctor]
 &#160;&#160;&#160;

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

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

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




<P>In an example like</P>

<PRE>
   struct A { A(int = 0); }; 
   struct B : A { using A::A; }; 
   B b0(0); //<SPAN style="font-family:Times;font-style:italic"> #1 </SPAN>
   B b;     //<SPAN style="font-family:Times;font-style:italic"> #2 </SPAN>
</PRE>

<P>Is #2 valid (presumably calling the constructor inherited from
<TT>A</TT>, or ill-formed due to ambiguity with <TT></TT>'s implicit
default constructor?</P>

<P><B>Proposed resolution (May, 2017):</B></P>

<OL><LI><P>Change 10.3.3 [namespace.udecl] paragraph 16 as follows:</P></LI>

<BLOCKQUOTE>

For the purpose of <SPAN style="font-weight:bold;background-color:#A0FFA0">forming a set of candidates during</SPAN>
overload resolution, the functions that are introduced by
a <I>using-declaration</I> into a derived class are treated as
though they were members of the derived class. In particular, the
implicit <TT>this</TT> parameter shall be treated as if it were a
pointer to the derived class rather than to the base class. This
has no effect on the type of the function, and in all other
respects the function remains a member of the base
class. Likewise, constructors that are introduced by
a <I>using-declaration</I> are treated as though they were
constructors of the derived class when looking up the
constructors of the derived class (6.4.3.1 [class.qual])
or forming a set of overload candidates
(16.3.1.3 [over.match.ctor], 16.3.1.4 [over.match.copy],
16.3.1.7 [over.match.list]). If such a constructor is selected
to perform the initialization of an object of class type, all
subobjects other than the base class from which the constructor
originated are implicitly initialized
(15.6.3 [class.inhctor.init]). <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> A member of a
derived class is sometimes preferred to a member of a base class
if they would otherwise be ambiguous
(16.3.3 [over.match.best]).  &#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

<LI><P>Insert the following as a new bullet following
16.3.3 [over.match.best] bullet 1.7:</P></LI>

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

<LI><P><TT>F1</TT> and <TT>F2</TT> are function template
specializations, and the function template for <TT>F1</TT> is
more specialized than the template for <TT>F2</TT> according to
the partial ordering rules described in
17.5.6.2 [temp.func.order], or, if not that,</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>F1</TT> is a constructor for a class <TT>D</TT>,
<TT>F2</TT> is a constructor for a base class <TT>B</TT> of
<TT>D</TT>, and for all arguments the corresponding parameters of
<TT>F1</TT> and <TT>F2</TT> have the same
type. [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  struct A {
    A(int = 0);
  };

  struct B: A {
    using A::A;
    B();
  };

  int main() {
    B b;  //<SPAN style="font-family:Times;font-style:italic"> OK, </SPAN>B::B()
  }</SPAN>
</PRE>

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

</LI>

<LI><P><TT>F1</TT> is generated from a <I>deduction-guide</I>
(16.3.1.8 [over.match.class.deduct])...</P></LI>

</UL>

</OL>

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

<BR><BR><HR><A NAME="2277"></A><H4>2277.
  
Ambiguity inheriting constructors with default arguments
</H4><B>Section: </B>16.3.3.2&#160; [over.ics.rank]
 &#160;&#160;&#160;

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

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

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




<P>In an example like:</P>

<PRE>
  struct A { 
    A(int, int = 0); 
    void f(int, int = 0); 
  }; 
  struct B : A { 
    B(int); using A::A; 
    void f(int); using A::f; 
  } 
</PRE>

<P>calls to <TT>B(int)</TT> and <TT>B::f(int)</TT> are ambiguous,
because they could equally call the version inherited from the
base class. This doesn't match the intent in
10.3.3 [namespace.udecl], which usually makes derived-class
functions take precedence over ones from a base class.</P>

<P>The above patterns are not common, although they sometimes
cause breakage when refactoring a base class. However,
P0136R1 brings this into sharp focus, because it causes the
rejection of the following formerly-valid and very reasonable
code:</P>

<PRE>
  struct A { 
    A(int = 0); 
  }; 
  struct B : A { 
    using B::B; 
  }; 
  B b; 
</PRE>

<P><B>Proposed resolution (May, 2017):</B></P>

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

<BR><BR><HR><A NAME="2287"></A><H4>2287.
  
Pointer-interconvertibility in non-standard-layout unions
</H4><B>Section: </B>6.9.2&#160; [basic.compound]
 &#160;&#160;&#160;

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

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

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




<P>According to 12.3 [class.union] paragraph 2,</P>

<BLOCKQUOTE>

 [<I>Note:</I> A union object and its non-static data members are
 pointer-interconvertible (6.9.2 [basic.compound],
 8.2.9 [expr.static.cast]). As a consequence, all non-static
 data members of a union object have the same
 address. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>However, the normative wording now only requires this for
standard-layout unions.</P>

<P><B>Proposed resolution (April, 2017):</B></P>

<P>Change 6.9.2 [basic.compound] bullet 4.2 as follows:</P>

<BLOCKQUOTE>

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

<UL><LI><P>they are the same object, or</P></LI>

<LI><P>one is a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">standard-layout</SPAN> union object and the
other is a non-static data member of that object
(12.3 [class.union]), or</P></LI>

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

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="2290"></A><H4>2290.
  
Unclear specification for overload resolution and deleted special member functions
</H4><B>Section: </B>16.3.1&#160; [over.match.funcs]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Howard Hinnant
 &#160;&#160;&#160;

 <B>Date: </B>2016-07-21




<P>According to 16.3.1 [over.match.funcs] paragraph 8,</P>

<BLOCKQUOTE>

A defaulted move constructor or assignment operator
(15.8 [class.copy]) that is defined as deleted is
excluded from the set of candidate functions in all contexts.

</BLOCKQUOTE>

<P>It is unclear whether this is intended to apply to all
defaulted assignment operators or only move assignment
operators.</P>

<P><B>Proposed resolution (April, 2017):</B></P>

<P>Change 16.3.1 [over.match.funcs] paragraph 8 as follows:</P>

<BLOCKQUOTE>

A defaulted move <SPAN style="text-decoration:line-through;background-color:#FFA0A0">constructor or assignment operator</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">special function</SPAN> (15.8 [class.copy]) that is
defined as deleted is excluded from the set of candidate
functions in all contexts.

</BLOCKQUOTE>

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