The rule is simple: if the generated definition satisfies the requirements of the constexpr function, then it will be the constexpr function. For example, from C ++ 17, [class.ctor] / 7:
If this custom default constructor satisfies the requirements of the constexpr constructor (10.1.5), the implicitly defined default constructor is constexpr .
The language around implicit default constructors is described in terms of what the "custom default constructor" will look like. So, "this custom default constructor" means "what the compiler generates."
A similar formulation exists for copy / move constructors.
Conditional wording is somewhat more complicated for assignment operators, but it comes down to the same thing. The type must be literal, and the assignment operators selected for copy / move for each subobject (non-static data element and base class) must be constexpr .
source share