Search code examples
constructorc++14constexprassignment-operatorc++17

Constexpr implicitly declared functions


For a class of type T, the following members can be generated by the compiler, depending on the class:

  • default constructor: T::T()
  • copy constructor: T::T(const T&)
  • move constructor: T::T(T&&)
  • copy assignment operator: T& T::operator=(const T&)
  • move assignment operator: T& T::operator=(T&&)

In C++14, and in C++17, what are the rules that lead to the generation of constexpr versions of these functions by the compiler?


Solution

  • The rule is simple: if the generated definition satisfies the requirements of a constexpr function, then it will be a constexpr function. For example, from C++17, [class.ctor]/7:

    If that user-written default constructor would satisfy the requirements of a constexpr constructor (10.1.5), the implicitly-defined default constructor is constexpr.

    The wording around implicit default constructors is describes in terms of what a "user-written default constructor" would look like. So "that user-written default constructor" means "what the compiler generates".

    Similar wording exists for the copy/move constructors.

    The wording is slightly more complex for the assignment operators, but it boils down to the same thing. The type must be a literal type and the assignment operators selected to do the copy/move for each subobject (non-static data member and base class) must be constexpr.