For a class of type T, the following members can be generated by the compiler, depending on the class:
T::T()
T::T(const T&)
T::T(T&&)
T& T::operator=(const T&)
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?
constexpr functions are implicitly inline , but not implicitly static . Note that constexpr functions can be evaluated in a runtime context sometimes.
Also, note that constexpr variables are inline implicitly, so there's no need to use constexpr inline myVar = 10; .
constexpr functions A constexpr function is one whose return value is computable at compile time when consuming code requires it. Consuming code requires the return value at compile time to initialize a constexpr variable, or to provide a non-type template argument.
In C++11, constexpr member functions are implicitly const.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With