<html>
<style>
ins {background-color:#A0FFA0}
del {background-color:#FFA0A0}
</style>
<title>Redrafting: issues 667, 861, 990, 818</title>
<body>
Jason Merrill, John Spicer
<br>2010-03-12
<br>N3079=10-0069

<h1>Redrafting: issues 667, 861, 990, 818</h1>

<h2>Introduction</h2>

This paper contains drafting for various core issues that were not in the
pre-meeting mailing (818), or are slightly revised from what was in the
pre-meeting mailing.

<br><a href="#667">Issue 667</a>
<br><a href="#990">Issue 990</a>
<br><a href="#818">Issue 818</a>
<br><a href="#861">Issues 861, 919, 920</a>

<h2>Issue 667 Proposed Resolution</h2>
8.4 [dcl.fct.def]:
<blockquote>
  Only special member functions may be explicitly defaulted<ins>.
  Explicitly-defaulted functions and implicitly-declared functions are
  collectively called <i>defaulted</i> functions</ins>, and the
  implementation shall <del>define them as if they
  had</del><ins>provide</ins> implicit definitions <ins>for them</ins>
  (12.1 [class.ctor], 12.4 [class.dtor], 12.8 [class.copy])<ins>, which
  might mean defining them as deleted</ins>. <del>A special member function
  that would be implicitly defined as deleted may be explicitly defaulted
  only on its first declaration, in which case it is defined as
  deleted.</del>  A special member function is user-provided if it is
  user-declared and not explicitly defaulted on its first declaration. A
  user-provided explicitly-defaulted function is defined at the point where
  it is explicitly defaulted<ins>; if such a function is implicitly defined
  as deleted, the program is ill-formed</ins>.

</blockquote>

12.1 [class.ctor]/5:
<blockquote>...  If there is no user-declared constructor for class X, a
  constructor having no parameters is implicitly declared <ins>as defaulted (8.4)</ins>.  An
  implicitly-declared default constructor is an inline public member of its
  class.  <del>A default constructor is trivial if it is not
    user-provided (8.4) and if:</del>
  <ul>
    <li> <del>its class has no virtual functions (10.3) and no virtual base classes (10.1), and</del> </li>
    <li><del> no non-static data member of its class has a brace-or-equal-initializer, and</del></li>
    <li><del> all the direct base classes of its class have trivial default constructors, and</del></li>
    <li><del> for all the non-static data members of its class that are of class type (or array thereof), each such class has a trivial default constructor.</del></li>
  </ul>
  <p>A<del>n implicitly-declared</del> <ins>defaulted</ins> default constructor for class X is defined as deleted if:
    <ul>
      <li>X is a union-like class that has a variant member with a non-trivial default constructor,</li>
      <li> any non-static data member is of reference type,</li>
      <li> any non-static data member of const-qualified type (or array thereof) does not have a user-provided default constructor, or</li>
      <li> any non-static data member or direct or virtual base class has class type M (or array thereof) and M has no default constructor, or if overload resolution (13.3) as applied to M's default constructor, results in an ambiguity or a function that is deleted or inaccessible from the <del>implicitly-declared</del><ins>defaulted</ins> default constructor.</li>
    </ul>
  </p>
  <p><ins>A default constructor is trivial if it is neither
      user-provided nor deleted and if:</ins>
  <ul>
    <li> <ins>its class has no virtual functions (10.3) and no virtual base classes (10.1), and</ins> </li>
    <li><ins> no non-static data member of its class has a brace-or-equal-initializer, and</ins></li>
    <li><ins> all the direct base classes of its class have trivial default constructors, and</ins></li>
    <li><ins> for all the non-static data members of its class that are of class type (or array thereof), each such class has a trivial default constructor.</ins></li>
  </ul></p>
  <p>Otherwise, the default constructor is non-trivial.</p>

  <p>A <del>non-user-provided</del> default constructor
  <del>for a class</del> <ins>that is defaulted and not defined as
  deleted</ins> is implicitly defined when it is used (3.2) to create an
  object of its class type (1.8)<ins>, or when it is explicitly defaulted
  after its first declaration</ins>.  The implicitly-defined <del>or explicitly-defaulted</del>
  default constructor performs the set of initializations of the class that
  would be performed by a user-written default constructor for that class
  with no ctor-initializer (12.6.2) and an empty compound-statement. If
  that user-written default constructor would be ill-formed, the program is
  ill-formed.  If that user-written default constructor would satisfy the
  requirements of a constexpr constructor (7.1.5), the implicitly-defined
  default constructor is constexpr. Before
  the <del>non-user-provided</del><ins>defaulted</ins> default constructor
  for a class is implicitly defined, all
  the non-user-provided default constructors
  for its base classes and its non-static data members shall have been
  implicitly defined. [ Note: an implicitly-declared default constructor
  has an exception-specification (15.4). An explicitly-defaulted definition
  has no implicit exception-specification.  --end note ]
  </p>
</blockquote>

12.4 [class.dtor]/3:
<blockquote>
  If a class has no user-declared destructor, a destructor is <del>declared</del>
  implicitly <ins>declared as defaulted (8.4)</ins>. An implicitly-declared destructor is an inline public member
  of its class. <del>If the class is a union-like class that has a variant
  member with a non-trivial destructor, an implicitly-declared destructor
    is defined as deleted (8.4).</del> <del>A destructor is trivial if it is not
    user-provided and if:</del>
    <ul>
      <li><del> the destructor is not virtual,</del></li>
      <li><del> all of the direct base classes of its class have trivial destructors, and</del>
      <li><del> for all of the non-static data members of its class that
         are of class type (or array thereof), each such class has a
         trivial destructor.</del>
    </li></ul>
  A<del>n implicitly-declared</del> <ins>defaulted</ins> destructor for a class X is defined as deleted if:
    <ul>
      <li> X is a union-like class that has a variant member with a non-trivial destructor,
      <li> any of the non-static data members has class type M (or array thereof) and M has an deleted destructor
        or a destructor that is inaccessible from the <del>implicitly-declared</del><ins>defaulted</ins> destructor, or
      <li> any direct or virtual base class has a deleted destructor or a destructor that is inaccessible from the
        <del>implicitly-declared</del><ins>defaulted</ins> destructor.</li>
    </ul>
<ins>A destructor is trivial if it is neither
    user-provided nor deleted and if:</ins>
    <ul>
      <li><ins> the destructor is not virtual,</ins></li>
      <li><ins> all of the direct base classes of its class have trivial destructors, and</ins>
      <li><ins> for all of the non-static data members of its class that
         are of class type (or array thereof), each such class has a
         trivial destructor.</ins>
    </li></ul>
  Otherwise, the destructor is non-trivial.

<p>A <del>non-user-provided</del> destructor <ins>that is defaulted and not defined as
  deleted</ins> is implicitly defined when it is used to destroy an object of its class type (3.7)<ins>, or when it is explicitly defaulted
  after its first declaration</ins>.

  <del>A program is ill-formed if the class for which a destructor is implicitly defined or explicitly defaulted has:</del>
  <ul>
    <li><del>a non-static data member of class type (or array thereof) with an inaccessible destructor, or</del>
    <li><del>a base class with an inaccessible destructor.</del>
  </li></ul>

  Before the <del>non-user-provided</del><ins>defaulted</ins> destructor for a class is
  implicitly defined, all the non-user-<del>defined</del><ins>provided</ins> destructors for its base
  classes and its non-static data members shall have been implicitly
  defined. [ Note: an implicitly-declared destructor has an
  exception-specification (15.4). An explictly defaulted definition has no
  implicit exception-specification. -- end note ]
  
</blockquote>

12.8 [class.copy]:
<blockquote>
  If the class definition does not explicitly declare a copy constructor, one is <del>declared</del> implicitly <ins>declared as defaulted (8.4)</ins>.

  <p>....</p>
  
  An implicitly-declared copy constructor is an inline public member of its class. A<del>n implicitly-declared</del><ins>defaulted</ins>
  copy constructor for a class X is defined as deleted if X has:
  <ul>
     <li> a variant member with a non-trivial copy constructor and X is a union-like class,
     <li> a non-static data member of class type M (or array thereof) that cannot be copied because overload
          resolution (13.3), as applied to M's copy constructor, results in an ambiguity or a function that is
          deleted or inaccessible from the <del>implicitly-declared</del><ins>defaulted</ins> copy constructor, or
     <li> a direct or virtual base class B that cannot be copied because overload resolution (13.3), as applied
          to B's copy constructor, results in an ambiguity or a function that is deleted or inaccessible from the
       <del>implicitly-declared</del><ins>defaulted</ins> copy constructor.</li>
  </ul>
  A copy constructor for class X is trivial if it is <del>not</del><ins>neither</ins> user-provided <ins>nor deleted</ins> <del>(8.4)</del> and if
  <ul>
     <li> class X has no virtual functions (10.3) and no virtual base classes (10.1), and
     <li> the constructor selected to copy each direct base class subobject is trivial, and
     <li> for each non-static data memberof X that is of class type (or array thereof), the constructor selected
          to copy that member is trivial;
  </ul>
  otherwise the copy constructor is non-trivial.
  <p>
  A <del>non-user-provided</del> copy constructor <ins>that is defaulted and not defined as
  deleted</ins> is implicitly defined if it is used to initialize an object of its class type
  from a copy of an object of its class type or of a class type derived from its class type [ Footnote .... ]<ins>, or when it is explicitly defaulted
  after its first declaration</ins>. [ Note: the copy
  constructor is implicitly defined even if the implementation elided its use (12.2). -- end note ] 
  <p>Before the <del>non-user-provided</del><ins>defaulted</ins> copy constructor for a class is implicitly defined, all non-user-provided copy
  constructors for its direct and virtual base classes and its non-static data members shall have been implicitly
  defined. [ Note: an implicitly-declared copy constructor has an exception-specification (15.4). An explicitly-
  defaulted definition has no implicit exception-specification. -- end note ]
  <p>The implicitly-defined <del>or explicitly-defaulted</del> copy constructor for a non-union class X performs a memberwise

  copy of its subobjects. [ Note: brace-or-equal-initializers of non-static data members are ignored. See also
  the example in 12.6.2. -- end note ] The order of copying is the same as the order of initialization of bases
  and members in a user-defined constructor (see 12.6.2). Each subobject is copied in the manner appropriate
  to its type:
  <ul>
     <li> if the subobject is of class type, the copy constructor for the class is used;
     <li> if the subobject is an array, each element is copied, in the manner appropriate to the element type;
     <li> if the subobject is of scalar type, the built-in assignment operator is used.
  </ul>
  Virtual base class subobjects shall be copied only once by the implicitly-defined copy constructor (see 12.6.2).
<p>  The implicitly-defined <del>or explicitly-defaulted</del> copy constructor for a union X copies the object representation (3.9)

  of X.
<p>....
<p>If the class definition does not explicitly declare a copy assignment operator, one is <del>declared</del> implicitly <ins>declared as defaulted (8.4)</ins>. 
<p>....
<p> An implicitly-declared copy
assignment operator is an inline public member of its class. A<del>n implicitly-declared</del><ins>defaulted</ins> copy assignment
operator for class X is defined as deleted if X has:
<ul>
  <li>a variant member with a non-trivial copy assignment operator and X is a union-like class,
  <li>a non-static data member of const non-class type (or array thereof), or
  <li>a non-static data member of reference type, or
  <li>a non-static data member of class type M (or array thereof) that cannot be copied because overload
    resolution (13.3), as applied to M's copy assignment operator, results in an ambiguity or a function
    that is deleted or inaccessible from the <del>implicitly-declared</del><ins>defaulted</ins> copy assignment operator, or
  <li>a direct or virtual base class B that cannot be copied because overload resolution (13.3), as applied to
    B’s copy assignment operator, results in an ambiguity or a function that is deleted or inaccessible from
    the <del>implicitly-declared</del><ins>defaulted</ins> copy assignment operator.
</ul>
   Because a copy assignment operator is implicitly declared for a class if not declared by the user, a base class
   copy assignment operator is always hidden by the copy assignment operator of a derived class (13.5.3). A
   using-declaration (7.3.3) that brings in from a base class an assignment operator with a parameter type that
   could be that of a copy-assignment operator for the derived class is not considered an explicit declaration
   of a copy-assignment operator and does not suppress the implicit declaration of the derived class copy-
   assignment operator; the operator introduced by the using-declaration is hidden by the implicitly-declared
   copy-assignment operator in the derived class.
<p>   A copy assignment operator for class X is trivial if it is <del>not</del><ins>neither</ins> user-provided <ins>nor deleted</ins> and if
<ul>
  <li>class X has no virtual functions (10.3) and no virtual base classes (10.1), and
  <li>the assignment operator selected to copy each direct base class subobject is trivial, and
  <li>for each non-static data memberof X that is of class type (or array
    thereof), the assignment operator selected to copy that member is
    trivial;
</ul>
   otherwise the copy assignment operator is non-trivial.
<p>
   A <del>non-user-provided</del> copy assignment operator <ins>that is
  defaulted and not defined as deleted</ins> is implicitly defined when an
  object of its class type is assigned a value of its class type or a value
  of a class type derived from its class type<ins>, or when it is
  explicitly defaulted after its first declaration</ins>.
<p>
   Before the <del>non-user-provided</del><ins>defaulted</ins> copy
   assignment operator for a class is implicitly defined,
   all non-user-provided copy assignment
   operators for its direct base classes and its non-static data members
   shall have been implicitly defined.

   [ Note: an implicitly-declared copy assignment operator has an
   exception-specification (15.4).  An explicitly-defaulted definition has
   no implicit exception-specification. -- end note ]
<p>
   The implicitly-defined <del>or explicitly-defaulted</del> copy
   assignment operator for a non-union class X performs memberwise
   assignment of its subobjects. The direct base classes of X are assigned
   first, in the order of their declaration in the base-specifier-list, and
   then the immediate non-static data members of X are assigned, in the
   order in which they were declared in the class definition. Each
   subobject is assigned in the manner appropriate to its type:
   <ul>
      <li>if the subobject is of class type, the copy assignment operator for the class is used (as if by explicit
         qualification; that is, ignoring any possible virtual overriding functions in more derived classes);
      <li>if the subobject is an array, each element is assigned, in the manner appropriate to the element type;
      <li>if the subobject is of scalar type, the built-in assignment operator is used.
   </ul>
   It is unspecified whether subobjects representing virtual base classes are assigned more than once by the
   implicitly-defined <del>or explicitly-defaulted</del> copy assignment operator. [ Example:
<pre>
      struct  V { };
      struct  A : virtual V { };
      struct  B : virtual V { };
      struct  C : B, A { };
</pre>
   It is unspecified whether the virtual base class subobject V is assigned twice by the implicitly-defined copy
   assignment operator for C. -- end example ]
<p>   The implicitly-defined <del>or explicitly-defaulted</del> copy assignment operator for a union X copies the object
   representation (3.9) of X.
</blockquote>

<hr>
<a name="990" />
<h2>Issue 990 Proposed Resolution</h2>

Change 8.5.4 [dcl.init.list] paragraph 3 as follows:

<blockquote>
  List-initialization of an object or reference of type T is defined as follows:

  <ul>
    <li>
      <ins>If the initializer list has no elements
	and <tt>T</tt> is a class type with a default constructor, the object
	is value-initialized.</ins></li>
    <li><ins>Otherwise, if the initializer list has no elements and T is an
	aggregate, each of the members of T is initialized from an empty
	initializer list. [ <i>Example:</i></ins>
<pre>
  <ins>struct A {</ins>
    <ins>A(std::initializer_list&lt;int&gt;); // #1</ins>
  <ins>};</ins>
  <ins>struct B {</ins>
    <ins>A a;</ins>
  <ins>};</ins>
  <ins>B b { };   // OK, uses #1</ins>
  <ins>B b { 1 }; // error</ins>
</pre>

    <ins>-- <i>end example</i> ]</ins></li>
    <li><del>If</del><ins>Otherwise, if</ins> T is an aggregate ....</li>
    <li>Otherwise, if T is a specialization of std::initializer_list&lt;E&gt;, an
	initializer_list object is constructed as described below and used
	to initialize the object according to the rules for initialization
	of an object from a class of the same type (8.5).</li>
  <li>Otherwise, if T is a class type, constructors are considered. If T has an
  initializer-list constructor, the argument list consists of the
  initializer list as a single argument; otherwise, the argument list
  consists of the elements of the initializer list. The applicable
  constructors are enumerated (13.3.1.7) and the best one is chosen through
  overload resolution (13.3). If a narrowing conversion (see below) is
  required to convert any of the arguments, the program is ill-formed.

  <p>[ <i>Example</i>:
<pre>
   struct S {
      S(std::initializer_list&lt;double&gt;); // #1
      S(std::initializer_list&lt;int&gt;);    // #2
      <ins>S();                              // #3</ins>
      // ...
   };
   S s1 = { 1.0, 2.0, 3.0 };            // invoke #1
   S s2 = { 1, 2, 3 };                  // invoke #2
   <ins>S s3 = { };                          // invoke #3</ins>
</pre>
-- <i>end example</i> ]
  </p>...</li>
    <li>Otherwise, if T is a reference to class type or if T is any reference
      type and the initializer list has no elements ....</li>
    <li>Otherwise, if the initializer list has a single element ....</li>


    <li>Otherwise, if the initializer list has no elements, the object is value-initialized.
      <p>[ <i>Example:</i>
      <pre>
  int** pp {};   // <i>initialized to null pointer</i>
      </pre><i>-- end example</i> ]</p>
    </li>
    <li>Otherwise, the program is ill-formed. ...</li>
  </ul>
</blockquote>

<hr>
<a name="861" />

<h2>Issues 861, 919, 920 Proposed Resolution</h2>

<h4>Common text</h4>

7.3.1 [namespace.def]/9:
<blockquote>
  These properties are transitive: if a namespace N contains an inline
  namespace M, which in turn contains an inline namespace O, then the
  members of O can be used as though they were members of M or N. <ins>The
  transitive closure of all inline namespaces in N is the <i>inline
  namespace set</i> of N.</ins> The set of namespaces consisting of the
  innermost non-inline namespace enclosing an inline namespace O, together
  with any intervening inline namespaces, is the enclosing namespace set of
  O.
</blockquote>

<h4>Issue 861</h4>

3.4.3.2 [namespace.qual]:

<blockquote>
  If the nested-name-specifier of a qualified-id nominates a namespace, the
  name specified after the nested-name-specifier is looked up in the scope
  of the namespace, except that the names in a template-argument of a
  template-id are looked up in the context in which the entire
  postfix-expression occurs.
<p>
  <ins>For a namespace X and name m, the namespace-qualified lookup set
  S(X,m) is defined as follows:
      Let S'(X,m) be the set of all declarations of m in X and the inline
      namespace set of X (7.3.1).  If S'(X,m) is not empty, S(X,m) is
      S'(X,m); otherwise, S(X,m) is the union of S(N<sub>i</sub>,m) for all
      namespaces N<sub>i</sub> nominated by using-directives in X and its inline namespace set.
  </ins>
</p>
  Given X::m (where X is a user-declared namespace), or given ::m
  (where X is the global namespace), <del>let S be the set of all declarations of
    m in X and in the transitive closure of all namespaces nominated by
    using-directives in X and its used namespaces, except
    that using-directives that nominate non-inline namespaces (7.3.1) are
    ignored in any namespace, including X, directly
    containing one or more declarations of m.

  No namespace is searched more than once in the lookup of a name.  I</del>
<ins>i</ins>f S<ins>(X,m)</ins> is the empty set, the program is ill-formed. 
Otherwise, if S<ins>(X,m)</ins> has exactly one member, or if the context of the reference is a
using-declaration (7.3.3), S<ins>(X,m)</ins> is the required set of declarations of
m. Otherwise if the use of m is not one that allows a unique declaration to
be chosen from S<ins>(X,m)</ins>, the program is ill-formed.

</blockquote>


<h4>Issue 919</h4>

[class]/11:

<blockquote>If a class-head contains a nested-name-specifier, the
class-specifier shall refer to a class that was previously declared
directly in the class or namespace to which the nested-name-specifier
refers<ins>, or in an element of the inline namespace set ([namespace.def])
of that namespace (i.e., not merely</ins><del>(i.e., neither</del>
inherited <del>n</del>or introduced by a using-declaration), and the
class-specifier shall appear in a namespace enclosing the previous
declaration.</blockquote>

[namespace.qual]/6:

<blockquote> In a declaration for a namespace member in which the declarator-id is a
qualified-id, given that the qualified-id for the namespace member has the
form
<pre>
        nested-name-specifier unqualified-id
</pre>
the unqualified-id shall name a member of the namespace designated by the
nested-name-specifier<ins>, or of an element of the inline namespace set
([namespace.def]) of that namespace</ins>.</blockquote>

<h4>Issue 920</h4>

[dcl.meaning]/1:

<blockquote>...  When the declarator-id is qualified, the declaration shall
  refer to a previously declared member of the class or namespace to which
  the qualifier refers (or<ins>, in the case of a namespace,</ins> of
  an <ins>element of the</ins> inline namespace <ins>set
    of</ins><del>within</del> that <del>scope</del><ins>namespace</ins> (7.3.1))<del>,
  and</del><ins>;</ins> the member shall not <ins>merely</ins> have been
  introduced by a using-declaration in the scope of the class or namespace
  nominated by the nested-name-specifier of the declarator-id.</blockquote>

<hr>
<a name="818" />
<H2>
Issue 818 Drafting
</H2>
<h3>
Function parameter packs in non-final positions
</h3>

<p>
Modify 8.3.5 [dcl.fct] paragraph 13 as follows:

<BLOCKQUOTE>
<del>
A function parameter pack, if present, shall occur at the end of the
parameter-declaration-list.
</del>
</BLOCKQUOTE>

<p>
Modify 14.9.2.1 paragraph 1 as follows:
<BLOCKQUOTE>
For a function parameter pack
<ins>
that occurs at the end of the
parameter-declaration-list
</ins>,
the type A of each remaining argument
of the call is compared with the type P of the <em>declarator-id</em> of the
function parameter pack. Each comparison deduces template arguments
for subsequent positions in the template parameter packs expanded by
the function parameter pack.
<ins>
For a function parameter pack that does not occur at the end of the
parameter-declaration-clause, the type of the parameter pack is a
non-deduced context.
</ins>
<del>
[Note: A function parameter pack can only occur at the end of a
parameter-declaration-list (8.3.5). --end note ]
</del>
</BLOCKQUOTE>

<p>
Add a bullet to 14.9.2.5 [temp.deduct.type] paragraph 5:

<BLOCKQUOTE>
The non-deduced contexts are:

<p>
...

<bl>
<li>
<ins>
A function parameter pack that does not occur at the end of the
parameter-declaration-clause.
</ins>
</bl>
</BLOCKQUOTE>


</body>
</html>
