Search code examples
c++c++11c++14initializer-listlist-initialization

Issue with std::initializer_list constructor and "braced initialization"


Consider the following code:

#include <initializer_list>

class C {
public:
    C() = delete;
    C(int) {}
};

class D {
public:
    D(std::initializer_list<C> il) {} 
};

int main()
{
    std::initializer_list<C> il{};  // fine: empty list, no need to construct C
    D d2(il);                       // fine: calls initializer_list ctor with empty list
    D d3{il};                       // ditto
    D d4({});                       // still fine
    D d5{{}};                       // error: use of deleted function 'C::C()' 
                                    // WHY is the constructor of 'C' required here?
}

I thought D d5{{}}; would call the initializer_list constructor of D with an empty list. And, as the list is empty, the constructor of C would not be called. However, it does not compile:

error: use of deleted function 'C::C()' -- D d5{{}};

What is the rationale behind this error?

Update

An issue on page 55 in Scott Meyer's "Effective Modern C++" made me think that having empty braces in a braced initialization would call the initializer_list constructor with an empty list. That is wrong. For details, see this blog post from the author.


Solution

  • D d5{{}}; attempts to initialize d5 with a one-element initializer list. That one element is {} which is a shorthand for C{} - a default-constructed instance of C. But C doesn't have a default constructor - hence the error.