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
Consider:
struct A { A(); A(A const&) = delete; }; int main(){ A a = A(A(A())); // #1 A b = A{A{A{}}}; // #2 }
#1 is well-formed per 9.4.1 [dcl.init.general] bullet 16.6.1. However, even though #2 is intended to have a similar effect, the relevant rule excludes non-aggregates, making the example ill-formed (because the relevant constructor is deleted); see 9.4.5 [dcl.init.list] bullet 3.2:
If T is 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).
There is implementation divergence: gcc and clang accept, MSVC rejects.
See also issue 2311.
Suggested resolution:
Change in 9.4.5 [dcl.init.list] bullet 3.2 as follows:
If T isan aggregate classa class type 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).
CWG 2024-03-01
Recent MSVC no longer rejects the example. The suggested resolution would revert issue 2137, which is not desirable. The consensus is to try an initializer-list constructor first and then fall back to copy-initialization (with guaranteed copy elision). A change to 12.2.4.2.6 [over.ics.list] may be necessary.