Created on 2015-06-10.00:00:00 last changed 106 months ago
Proposed resolution (April, 2016):
Change 9.5.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...
[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:00 | admin | set | messages: + msg6102 |
| 2017-02-06 00:00:00 | admin | set | status: drafting -> cd4 |
| 2015-06-10 00:00:00 | admin | create | |