constexpr specifier (since C++11)
-
-
constexpr
- specifies that the value of a variable or function can appear in constant expressions
-
Contents |
[edit] Explanation
The constexpr
specifier declares that it is possible to evaluate the value of the function or variable at compile time. Such variables and functions can then be used where only compile time constant expressions are allowed. A constexpr specifier used in an object declaration implies const. A constexpr specifier used in an function declaration implies inline.
A constexpr variable must satisfy the following requirements:
-
- its type must be a
LiteralType
. - it must be immediately constructed or assigned a value.
- the constructor parameters or the value to be assigned must contain only literal values,
constexpr
variables and functions. - the constructor used to construct the object (either implicit or explicit) must satisfy the requirements of
constexpr
constructor. In the case of explicit constructor, it must have constexpr specified.
- its type must be a
A constexpr function must satisfy the following requirements:
-
- it must not be virtual
- its return type must be
LiteralType
- each of its parameters must be literal type
|
(until C++14) |
|
(since C++14) |
A constexpr constructor must satisfy the following requirements:
-
- each of its parameters must be literal type
- the class must have no virtual base classes
- the constructor must not have a function-try-block
|
(until C++14) |
|
(since C++14) |
A non-template, non-defaulted constexpr
function or a non-template, non-defaulted, non-inheriting constexpr
constructor must yield a core constant expression when appropriate arguments are provided.
At least one specialization of a constexpr
function template must satisfy the above requirements. Other specializations are still considered constexpr
even though it is impossible to call them in a constant expression.
Note that if a constexpr
function is called in an constant expression, its executed branch must meet the requirements for constant expressions. For example, the executed branch must not contain an invocation of a non-constexpr
function.
[edit] Keywords
[edit] Example
Definition of a constexpr function which computes factorials and a literal type that extends string literals:
#include <iostream> #include <stdexcept> // constexpr functions use recursion rather than iteration constexpr int factorial(int n) { return n <= 1 ? 1 : (n * factorial(n-1)); } // literal class class conststr { const char * p; std::size_t sz; public: template<std::size_t N> constexpr conststr(const char(&a)[N]) : p(a), sz(N-1) {} // constexpr functions signal errors by throwing exceptions from operator ?: constexpr char operator[](std::size_t n) const { return n < sz ? p[n] : throw std::out_of_range(""); } constexpr std::size_t size() const { return sz; } }; constexpr std::size_t countlower(conststr s, std::size_t n = 0, std::size_t c = 0) { return n == s.size() ? c : s[n] >= 'a' && s[n] <= 'z' ? countlower(s, n+1, c+1) : countlower(s, n+1, c); } // output function that requires a compile-time constant, for testing template<int n> struct constN { constN() { std::cout << n << '\n'; } }; int main() { std::cout << "4! = " ; constN<factorial(4)> out1; // computed at compile time volatile int k = 8; // disallow optimization using volatile std::cout << k << "! = " << factorial(k) << '\n'; // computed at run time std::cout << "Number of lowercase letters in \"Hello, world!\" is "; constN<countlower("Hello, world!")> out2; // implicitly converted to conststr }
Output:
4! = 24 8! = 40320 Number of lowercase letters in "Hello, world!" is 9