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?
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.