Question:
For the default constructor,
how is an empty body different from what happens with =default
?
X::X() {}
// и
X::X() = default;
Answer:
Having a default constructor with an empty body automatically makes the class non-trivial . With all the ensuing features. For example makes the type not POD . It also excludes the possibility of using aggregate initialization:
#include <iostream>
#include <type_traits>
struct X {
//X() {}
X() = default;
int a;
int b;
};
int main( ) {
X x { 1, 2 }; // ошибка, если X - не тривиальный класс.
std::cout << std::boolalpha <<
std::is_trivial<X>::value << "\n";
}
By defining a constructor as = default
, the triviality of the class is preserved if it was before. In this case, this is equivalent to not explicitly mentioning the constructor in the class definition.
If a default constructor is defined as = default
outside the class definition, the constructor is still considered to be user-provided, and this also makes the class non-trivial .
A footnote to the Standard on this subject (8.4.2/5):
A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration.
The difference will also be observed when trying to create a const class object with a default constructor. For instance:
const X x;
will result in a compilation error when class X
is defined as:
struct X {
X() = default;
int i;
};
And it will compile successfully in the case of a user-provided default constructor:
struct X {
X() {}
int i;
};
Another point that demonstrates the difference occurs when using an empty initialization list when defining an object. For instance:
X x = { };
will cause all class members to be set to null if = default
or if there is no explicit constructor. If the constructor is defined with an empty body, then such a record will leave the class members uninitialized (garbage).