Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy elision for list-initialization, where is it stated in the standard?

In [dcl.init]/17.6, it is explicitly written that for the case of parenthesis initialization, copy elision occurs:

If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object. [ Example: T x = T(T(T())); calls the T default constructor to initialize x.  — end example ]

But in the case of list-initialization, for which the above paragraph does not apply, I did not find anything similar. See [dcl.init.list].

So why is there copy elision in this case: T x{T(T())}; according to the C++17 standard.

like image 784
Oliv Avatar asked Mar 28 '18 12:03

Oliv


1 Answers

There is no copy elision in such case according to the current draft.

Consider the following example:

#include <iostream>
#include <initializer_list>

struct S {
    S() {std::cout << "default\n";}
    S(const S&) {std::cout << "copy\n";}
    S(std::initializer_list<S>) {std::cout << "initializer list\n";}
};

int main()
{
    S s = S{S()};
}

According to Core Language Issue 2137, the constructor taking std::initializer_list as parameter should be chosen (Clang may choose copy constructor or perform copy elision here, which is incorrect). So constructors are intended to be taken into consideration for such list initialization.

The problem is that when copy/move constructor is selected, it is reasonable to elide this copy/move. In fact, Core Language Issue 2327 has already addressed this defect.

like image 167
xskxzr Avatar answered Oct 04 '22 05:10

xskxzr