This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-10-26
[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?
Proposed resolution (April, 2016):
Change 9.4.5 [dcl.init.list] bullet 3.1 as follows:
List-initialization of an object or reference of type T is defined as follows:
If T is
a class typean 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)....
Change 12.2.4.2.6 [over.ics.list] paragraph 2 as follows:
If the parameter type isaan 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.
Change 12.2.4.2.6 [over.ics.list] paragraph 6 as follows, breaking the existing running text into a bulleted list:
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...