I have code like this for example :
class A {
public:
int x;
A() {
std::cout << "Constructor Called !" << std::endl;
}
A(int y):x(y) {
std::cout << "Constructor Param Called !" << std::endl;
}
A(const A& copy) {
std::cout << "Copy Constructor Called !" << std::endl;
}
}
class B {
public:
A value;
//B(const A& val) : value(val){}
}
int main(){
B b { A(22)};
}
If i comment out the B constructor the output is just "Constructor Param Called", but if i uncomment B constructor the output would be "Constructor Param Called" & "Copy Constructor Called". My questions :
- Why is the output different if i commented out the constructor ? (I've read about aggregate class & aggregate initialization, is this it ?)
- What's the difference between aggregate initialization & direct initialization ?
CodePudding user response:
When you remove the user-provided constructor for B
, B
becomes an aggregate. So aggregate-initialization is performed where each element of the class is copy-initialized from the elements of the initializer list. Since A(22)
is a prvalue of the same class as B
's element, copy-elision takes place where the value is stored directly into the object without any calls to the copy-constructor. This is new as of C 17.
When you declare the constructor for B
, it is no longer an aggregate, so constructors are considered when you're doing an initialization.
Direct-intialization just means there is no =
sign when you're initializing an object. Aggregate-initialization is what takes place when you're initializing an aggregate, and you can take a look at the definition on cppreference for that.