Direct initialization with empty initializer list

后端 未结 2 1695
误落风尘
误落风尘 2021-02-14 09:56
struct X
{
    X() { std::cout << \"default ctor\" << std::endl; }

};

int main()
{
    X({});
}

This prints out

default c         


        
2条回答
  •  眼角桃花
    2021-02-14 10:27

    To see what's really going on, declare copy and move constructors, compile in C++14 mode or earlier, and disable copy elision.

    Coliru link

    Output:

    default ctor
    move ctor
    

    In the first snippet, the compiler looks for constructors of X that take a single argument, since you've provided a single argument. These are the copy and move constructor, X::X(const X&) and X::X(X&&), which the compiler will implicitly declare for you if you do not declare them yourself. The compiler then converts {} to an X object using the default constructor, and passes that X object to the move constructor. (You must use fno-elide-constructors to see this otherwise the compiler will elide the move, and in C++17 copy elision became mandatory.)

    In the second snippet, the compiler now has a choice of converting {} to X (then calling the move constructor), or converting {} to std::initializer_list (then calling the initializer list constructor). According to [over.ics.list]/6.2, the conversion from {} to X, which calls the default constructor, is a user-defined conversion, while according to [over.ics.list]/4, the conversion from {} to std::initializer_list is the identity conversion. The identity conversion is better than a user-defined conversion, so the compiler calls the initializer list constructor.

提交回复
热议问题