The behavior of the default constructors is the same for A() {} and A() = default; per 12.1p6:
The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement.
The differences are:
- whether the constructor is
constexpr(an explicitly-defaulted constructor isconstexprif that would be valid), - whether the class is an aggregate (8.5.1p1), and
- whether value-initialization results in the default constructor being called, if the explicitly-defaulted default constructor is trivial (8.5p7).
For the last point:
#include <iostream> struct A { int i; A() = default; }; struct B { int j; B() {} }; int main() { int i = 42, j = 42; new (&i) A(); new (&j) B(); std::cout << i << std::endl; // 0 std::cout << j << std::endl; // 42 } So you might want to write a user-provided non-defaulted default constructor, if for example your class has trivial members that would be expensive to zero-initialize (e.g. a large array), but it's a very niche case.