Skip to main content
A defaulted function in C++ is an explicit instruction to the compiler to generate the standard, compiler-provided implementation for a special member function or, as of C++20, a comparison operator. By appending = default; to a function declaration, developers enforce the generation of default semantics while maintaining explicit visibility in the class interface.

Syntax

The = default specifier can be applied either inline within the class definition or out-of-line in the implementation file.

Applicability

The = default syntax cannot be applied to arbitrary member functions. It is strictly limited to functions the compiler is capable of generating implicitly. These include:
  • Default constructor: ClassName()
  • Copy constructor: ClassName(const ClassName&)
  • Move constructor: ClassName(ClassName&&)
  • Copy assignment operator: ClassName& operator=(const ClassName&)
  • Move assignment operator: ClassName& operator=(ClassName&&)
  • Destructor: ~ClassName()
  • C++20 and later: The three-way comparison operator (operator<=>) and all secondary comparison operators (operator==, operator!=, operator<, operator>, operator<=, operator>=).

Technical Mechanics and Rules

Signature Matching An explicitly defaulted function must generally possess a signature compatible with the implicitly declared version. However, the C++ standard provides specific exceptions:
  1. An explicitly defaulted copy constructor or copy assignment operator is permitted to take a non-const reference (T&) even if the implicitly generated version would require a const reference (const T&).
  2. Since C++14 (via CWG 1753), the return type of a defaulted assignment operator is allowed to differ from the implicit declaration (e.g., returning void or returning by value instead of T&).
If the declaration deviates in an incompatible way, the compiler’s behavior depends on the nature of the mismatch, the C++ version, and where the function is defaulted:
  • Exception Specification Mismatch (Inline): If a function is explicitly defaulted on its first declaration but has an exception specification that is incompatible with the implicitly generated one, the function is defined as deleted (= delete). This rule has applied since C++11.
  • Signature Mismatch (Inline): If the signature deviates in other incompatible ways (such as an invalid parameter type), the program is ill-formed in C++11, C++14, and C++17. In C++20 and later, the function is instead defined as deleted.
  • Out-of-Line Mismatch: If the function is explicitly defaulted out-of-line (after its initial declaration) and possesses any mismatch in signature or exception specification, the program is ill-formed and will fail to compile.
Access Control Unlike implicitly generated special member functions, which are always public, explicitly defaulted functions respect the access specifier under which they are declared. You can default a function under protected or private visibility to restrict its accessibility.
Impact on Triviality The location of the = default declaration directly impacts the triviality of the class type (e.g., std::is_trivial_v).
  • If a special member function is defaulted on its first declaration (inline within the class body), the function is considered trivial (provided all base classes and members also have trivial corresponding operations).
  • If the function is defaulted out-of-line (after its initial declaration), it is considered non-trivial, which can affect how the object is allocated, copied, or passed through ABIs.
Implicit Deletion If a function is explicitly defaulted, but the compiler is structurally unable to generate a valid implementation, the function is implicitly defined as deleted (= delete). For example, defaulting a default constructor in a class that contains an uninitialized reference member or a const member without a default initializer will result in a deleted constructor.
Tired of Poor C++ Skills? Fix That With Deep Grasping!Learn More