Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 909
Vincent Avatar asked May 14 '17 10:05

Vincent


People also ask

Is constexpr implicitly static?

constexpr functions are implicitly inline , but not implicitly static . Note that constexpr functions can be evaluated in a runtime context sometimes.

Is constexpr implicitly inline?

Also, note that constexpr variables are inline implicitly, so there's no need to use constexpr inline myVar = 10; .

What functions can be constexpr?

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.

Is constexpr implicitly const?

In C++11, constexpr member functions are implicitly const.


1 Answers

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.

like image 58
Nicol Bolas Avatar answered Sep 30 '22 09:09

Nicol Bolas