Created on 2023-06-06.00:00:00 last changed 8 months ago
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.
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).
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.
History | |||
---|---|---|---|
Date | User | Action | Args |
2024-03-03 21:57:08 | admin | set | messages: + msg7626 |
2024-03-03 21:57:08 | admin | set | status: open -> drafting |
2023-06-06 20:40:47 | admin | set | messages: + msg7305 |
2023-06-06 00:00:00 | admin | create |