c++ – How is an empty default constructor different from =default;?

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

Scroll to Top