Constant expressions
Defines an expression that can be evaluated at compile time.
Such expressions can be used as non-type template arguments, array sizes, and in other contexts that require constant expressions, e.g.
int n = 1; std::array<int, n> a1; // error, n is not a constant expression const int cn = 2; std::array<int, cn> a2; // OK, cn is a constant expression
Contents |
[edit] Core constant expressions
A core constant expression is any expression that does not have any one of the following in any subexpression (ignoring the unevaluated arguments of &&, ||, and ?:)
constexpr int n = std::numeric_limits<int>::max(); // OK, max() is constexpr constexpr int m = std::time(NULL); // Error: std::time() is not constexpr
constexpr
function which is declared, but not defined, if the function call itself is not made inside the body of a constexpr
function.constexpr
function with arguments that do not produce a constant expression when substituted
constexpr const int* addr(const int& ir) { return &ir; } static const int x = 5; constexpr const int* xp = addr(x); // OK constexpr const int* tp = addr(5); // error: &5 is not a constant expression
constexpr
function with arguments that do not produce constant expressions in member-initializer lists that are called from this function
int x; struct A { constexpr A(bool b) : m(b?42:x) { } int m; }; constexpr int v = A(true).m; // OK constexpr int w = A(false).m; // error: non-const x
constexpr
function that would exceed compile-time recursion depth limit (implementation-defined)
7) An expression whose result is not mathematically defined or is out of range for its type.
constexpr double d1 = 2.0/1.0; // OK constexpr double d2 = 2.0/0.0; // Error: not defined constexpr int n = std::numeric_limits<int>::max() + 1; // Error: overflow |
(until C++14) |
7) An expression whose evaluation leads to any form of core language (since C++17) undefined behavior (including signed integer overflow, division by zero, pointer arithmetic outside array bounds, etc). Whether standard library undefined behavior is detected is unspecified. (since C++17)
|
(since C++14) |
constexpr
or to its non-mutable subobject
12) conversion from cv void* to any pointer-to-object type
|
(since C++14) |
This section is incomplete Reason: needs more mini-examples and less standardese |
[edit] Integral constant expression
Integral constant expression is an expression of integral or unscoped enumeration type implicitly converted to a prvalue, where the converted expression is a core constant expression. If an expression of class type is used where an integral constant expression is expected, the expression is contextually implicitly converted to an integral or unscoped enumeration type.
- only integral constant expressions can be used as array bounds, the dimensions in new-expressions other than the first (until C++14), bit-field lengths, enumeration initializers when the underlying type is not fixed, null-pointer constants (until C++14), and alignments.
[edit] Converted constant expression
Converted constant expression is an expression implicitly converted to prvalue of type T, where the converted expression is a core constant expression, and the implicit conversion sequence contains only:
-
- constexpr user-defined conversions (so a class can be used where integral type is expected)
- lvalue-to-rvalue conversions
- integral promotions
- non-narrowing integral conversions
|
(since C++17) |
-
- And if any reference binding takes place, it is direct binding (not one that constructs a temporary object)
- Only converted constant expressions can be used as case expressions, enumerator initializers when the underlying type is fixed, array bounds, the dimensions in new-expressions other than the first (since C++14), and as integral and enumeration (until C++17)non-type template arguments.
[edit] Literal constant expression
Literal constant expression is a prvalue core constant expression of non-pointer literal type (after conversions as required by context). A literal constant expression of array or class type requires that each subobject is initialized with a constant expression.
[edit] Reference constant expression
Reference constant expression is an lvalue core constant expression that designates an object with static storage duration or a function.
[edit] Address constant expression
Address constant expression is a prvalue core constant expression (after conversions required by context) of type std::nullptr_t or of a pointer type, which points to an object with static storage duration, one past the end of an array with static storage duration, to a function, or is a null pointer.
[edit] Notes
Implementations are not permitted to declare library functions as constexpr unless the standard says the function is constexpr |
(since C++14) |
This section is incomplete Reason: examples |