Title
List-initialization from object of same type
Status
cd4
Section
9.4.5 [dcl.init.list]
Submitter
Richard Smith

Created on 2015-06-10.00:00:00 last changed 95 months ago

Messages

Date: 2016-04-15.00:00:00

Proposed resolution (April, 2016):

  1. Change 9.4.5 [dcl.init.list] bullet 3.1 as follows:

  2. List-initialization of an object or reference of type T is defined as follows:
    • If T is a class type an aggregate class and the initializer list has a single element of type cv U, where U is T or a class derived from T, the object is initialized from that element (by copy-initialization for copy-list-initialization, or by direct-initialization for direct-list-initialization).

    • ...

  3. Change 12.2.4.2.6 [over.ics.list] paragraph 2 as follows:

  4. If the parameter type is a an aggregate class X and the initializer list has a single element of type cv U, where U is X or a class derived from X, the implicit conversion sequence is the one required to convert the element to the parameter type.
  5. Change 12.2.4.2.6 [over.ics.list] paragraph 6 as follows, breaking the existing running text into a bulleted list:

  6. Otherwise, if the parameter is a non-aggregate class X and overload resolution per 12.2.2.8 [over.match.list] chooses a single best constructor C of X to perform the initialization of an object of type X from the argument initializer list, list:

    • If C is not an initializer-list constructor and the initializer list has a single element of type cv U, where U is X or a class derived from X, the implicit conversion sequence has Exact Match rank if U is X, or Conversion rank if U is derived from X

    • Otherwise, the implicit conversion sequence is a user-defined conversion sequence with the second standard conversion sequence an identity conversion.

    If multiple constructors are viable...

Date: 2016-06-15.00:00:00

[Adopted at the June, 2016 meeting.]

It is not clear in code like the following that selecting a copy/move constructor is the correct choice when an initializer list contains a single element of the type being initialized, as required by issue 1467:

  #include <initializer_list>
  #include <iostream>

  struct Q {
    Q() { std::cout << "default\n"; }
    Q(Q const&) { std::cout << "copy\n"; }
    Q(Q&&) { std::cout << "move\n"; }
    Q(std::initializer_list<Q>) { std::cout << "initializer list\n"; }
  };

  int main() {
    Q x = Q { Q() };
  }

Here the intent is that Q objects can contain other Q objects, but this is broken by the resolution of issue 1467.

Perhaps the presence of an initializer-list constructor should change the outcome?

History
Date User Action Args
2017-02-06 00:00:00adminsetmessages: + msg6102
2017-02-06 00:00:00adminsetstatus: drafting -> cd4
2015-06-10 00:00:00admincreate