Search code examples
c++constructorinitializationlanguage-lawyerlist-initialization

C++: how is construction by initialization list done?


C++ allows instantiating a class, setting the public members' value via an initialization list, as the example below shows for b1:

class B {
public:
    int i;
    std::string str;
}; 

B b1{ 42,"foo" };
B b2();

; however, if I provide a constructor

B(int k)    {   }

, it won't compile.

So, what's going on behind the hood? Is it that when no constructor is provide, the compiler will provide one? But how could it provide one with initialization list? I thought it will just provide a "blank" constructor taking no input, as the example shows for b2. Or does it provide both?


Solution

  • But how could it provide one with initialization list?

    No, it won't.

    Note that for list initialization B b1{ 42,"foo" };, aggregate initialization is performed.

    If T is an aggregate type, aggregate initialization is performed.

    And B is an aggregate type,

    An aggregate is one of the following types:

    array type
    class type (typically, struct or union), that has 
    
        no private or protected non-static data members
        no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed)
        no virtual, private, or protected base classes
        no virtual member functions
    

    That's why B b1{ 42,"foo" }; works well.

    And If you provide a user-defined constructor, B becomes non-aggregate type, then aggregate initialization won't work again. In this case, you can only initialize B like B b1{42}; or B b2(42);, which will call the appropriate constructor.

    BTW: After providing a user-defined constructor (taking one parameter), the implicitly-declared default constructor won't be declared by the compiler again. It means B b2; or B b2{}; won't work again.

    BTW2: B b2(); might be a function declaration. See Most vexing parse.