Title
Guaranteed copy elision for brace-initialization from prvalue
Status
drafting
Section
9.4.5 [dcl.init.list]
Submitter
Jim X

Created on 2023-06-06.00:00:00 last changed 1 month ago

Messages

Date: 2024-03-03.21:57:08

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.

Date: 2023-06-06.20:40:47

Suggested resolution:

Change in 9.4.5 [dcl.init.list] bullet 3.2 as follows:

If T is an aggregate class a 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).
Date: 2023-06-11.19:09:08

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:08adminsetmessages: + msg7626
2024-03-03 21:57:08adminsetstatus: open -> drafting
2023-06-06 20:40:47adminsetmessages: + msg7305
2023-06-06 00:00:00admincreate