constexpr
specifier(since C++11)General topics | ||||||||||||||||
Flow control | ||||||||||||||||
Conditional execution statements | ||||||||||||||||
Iteration statements (loops) | ||||||||||||||||
Jump statements | ||||||||||||||||
Functions | ||||||||||||||||
Function declaration | ||||||||||||||||
Lambda function expression | ||||||||||||||||
inline specifier | ||||||||||||||||
Dynamic exception specifications(until C++17*) | ||||||||||||||||
noexcept specifier(C++11) | ||||||||||||||||
Exceptions | ||||||||||||||||
Namespaces | ||||||||||||||||
Types | ||||||||||||||||
Specifiers | ||||||||||||||||
| ||||||||||||||||
Storage duration specifiers | ||||||||||||||||
Initialization | ||||||||||||||||
Expressions | ||||||||||||||||
Alternative representations | ||||||||||||||||
Literals | ||||||||||||||||
Boolean -Integer -Floating-point | ||||||||||||||||
Character -String -nullptr(C++11) | ||||||||||||||||
User-defined(C++11) | ||||||||||||||||
Utilities | ||||||||||||||||
Attributes(C++11) | ||||||||||||||||
Types | ||||||||||||||||
typedef declaration | ||||||||||||||||
Type alias declaration(C++11) | ||||||||||||||||
Casts | ||||||||||||||||
Memory allocation | ||||||||||||||||
Classes | ||||||||||||||||
Class-specific function properties | ||||||||||||||||
| ||||||||||||||||
Special member functions | ||||||||||||||||
Templates | ||||||||||||||||
Miscellaneous | ||||||||||||||||
|
constexpr
- specifies that the value of a variable,structured binding(since C++26) or function can appear inconstant expressionsContents |
Theconstexpr specifier declares that it is possible to evaluate the value of the entities at compile time. Such entities can then be used where only compile timeconstant expressions are allowed (provided that appropriate function arguments are given).
Aconstexpr specifier used in an object declaration or non-static member function(until C++14) impliesconst.
Aconstexpr specifier used in the first declaration of a function orstatic data member(since C++17) impliesinline. If any declaration of a function or function template has aconstexpr specifier, then every declaration must contain that specifier.
A variable or variable template(since C++14) can be declaredconstexpr if all following conditions are satisfied:
| (until C++26) |
| (since C++26) |
If aconstexpr variable is nottranslation-unit-local, it should not be initialized to refer to a translation-unit-local entity that is usable in constant expressions, nor have a subobject that refers to such an entity. Such initialization is disallowed in amodule interface unit (outside itsprivate module fragment, if any) or a module partition, and is deprecated in any other context. | (since C++20) |
A function or function template can be declaredconstexpr.
A function isconstexpr-suitable if all following conditions are satisfied:
| (until C++20) |
| (until C++23) |
| (since C++20) |
| (until C++14) | ||
| (since C++14) (until C++23) |
Except for instantiatedconstexpr functions, non-templatedconstexpr functions must be constexpr-suitable.
For a non-constructorconstexpr function that is neither defaulted nor templated, if no argument values exist such that an invocation of the function could be an evaluated subexpression of acore constant expression, the program is ill-formed, no diagnostic required. For a templatedconstexpr function, if no specialization of the function/class template would make the templated function constexpr-suitable when considered as a non-templated function, the program is ill-formed, no diagnostic required. | (until C++23) |
An invocation of aconstexpr function in a given context produces the same result as an invocation of an equivalent non-constexpr function in the same context in all respects, with the following exceptions:
On top of the requirements ofconstexpr functions, a constructor also needs to satisfy all following conditions to be constexpr-suitable:
| (until C++23) |
For aconstexpr constructor that is neither defaulted nor templated, if no argument values exist such that an invocation of the function could be an evaluated subexpression of the initialization full-expression of some object subject toconstant expression, the program is ill-formed, no diagnostic required. | (until C++23) |
Destructors cannot beconstexpr, but atrivial destructor can be implicitly called in constant expressions. | (until C++20) | ||
On top of the requirements ofconstexpr functions, a destructor also needs to satisfy all following conditions to be constexpr-suitable:
| (since C++20) |
Because the constexprint f();constexprbool b1=noexcept(f());// false, undefined constexpr functionconstexprint f(){return0;}constexprbool b2=noexcept(f());// true, f() is a constant expression | (until C++17) |
It is possible to write a constexpr function whose invocation can never satisfy the requirements of a core constant expression: void f(int& i)// not a constexpr function{ i=0;} constexprvoid g(int& i)// well-formed since C++23{ f(i);// unconditionally calls f, cannot be a constant expression} | (since C++23) |
Constexpr constructors are permitted for classes that are not literal types. For example, the default constructor ofstd::shared_ptr is constexpr, allowingconstant initialization.
Reference variables can be declared constexpr (their initializers have to bereference constant expressions):
staticconstexprintconst& x=42;// constexpr reference to a const int object// (the object has static storage duration// due to life extension by a static reference)
Even thoughtry blocks and inline assembly are allowed in constexpr functions, throwing exceptionsthat are uncaught(since C++26) or executing the assembly is still disallowed in a constant expression. If a variable has constant destruction, there is no need to generate machine code in order to call destructor for it, even if its destructor is not trivial. A non-lambda, non-special-member, and non-templated constexpr function cannot implicitly become an immediate function. Users need to explicitly mark itconsteval to make such an intended function definition well-formed. | (since C++20) |
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_constexpr | 200704L | (C++11) | constexpr |
201304L | (C++14) | Relaxedconstexpr,non-constconstexpr methods | |
201603L | (C++17) | Constexpr lambda | |
201907L | (C++20) | Trivialdefault initialization andasm-declaration inconstexpr functions | |
202002L | (C++20) | Changing the active member of a union in constant evaluation | |
202110L | (C++23) | Non-literal variables, labels, andgoto statements in constexpr functions | |
202207L | (C++23) | Relaxing someconstexpr restrictions | |
202211L | (C++23) | Permittingstaticconstexpr variables inconstexpr functions | |
202306L | (C++26) | Constexpr cast fromvoid*: towards constexpr type-erasure | |
__cpp_constexpr_in_decltype | 201711L | (C++11) (DR) | Generation of function and variable definitions whenneeded for constant evaluation |
__cpp_constexpr_dynamic_alloc | 201907L | (C++20) | Operations for dynamic storage duration inconstexpr functions |
Defines C++11/14constexpr functions that compute factorials; defines a literal type that extends string literals:
#include <iostream>#include <stdexcept> // C++11 constexpr functions use recursion rather than iterationconstexprint factorial(int n){return n<=1?1:(n* factorial(n-1));} // C++14 constexpr functions may use local variables and loops#if __cplusplus >= 201402Lconstexprint factorial_cxx14(int n){int res=1;while(n>1) res*= n--;return res;}#endif // C++14 // A literal classclass conststr{constchar* p;std::size_t sz;public:template<std::size_t N>constexpr conststr(constchar(&a)[N]): p(a), sz(N-1){} // constexpr functions signal errors by throwing exceptions// in C++11, they must do so from the conditional operator ?:constexprchar operator[](std::size_t n)const{return n< sz? p[n]:throwstd::out_of_range("");} constexprstd::size_t size()const{return sz;}}; // C++11 constexpr functions had to put everything in a single return statement// (C++14 does not have that requirement)constexprstd::size_t countlower(conststr s,std::size_t n=0,std::size_t c=0){return n== s.size()? c:'a'<= s[n]&& s[n]<='z'? countlower(s, n+1, c+1): countlower(s, n+1, c);} // An output function that requires a compile-time constant, for testingtemplate<int n>struct constN{ constN(){std::cout<< n<<'\n';}}; int main(){std::cout<<"4! = "; constN<factorial(4)> out1;// computed at compile time volatileint k=8;// disallow optimization using volatilestd::cout<< k<<"! = "<< factorial(k)<<'\n';// computed at run time std::cout<<"The number of lowercase letters in\"Hello, world!\" is "; constN<countlower("Hello, world!")> out2;// implicitly converted to conststr constexprint a[12]={0,1,2,3,4,5,6,7,8};constexprint length_a= sizeof a/ sizeof(int);// std::size(a) in C++17,// std::ssize(a) in C++20std::cout<<"Array of length "<< length_a<<" has elements: ";for(int i=0; i< length_a;++i)std::cout<< a[i]<<' ';std::cout<<'\n';}
Output:
4! = 248! = 40320The number of lowercase letters in "Hello, world!" is 9Array of length 12 has elements: 0 1 2 3 4 5 6 7 8 0 0 0
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 1358 | C++11 | templatedconstexpr functions also needed to have at least one valid argument value | no need |
CWG 1359 | C++11 | constexpr union constructors must initialize all data members | initializes exactly one data member for non-empty unions |
CWG 1366 | C++11 | classes withconstexpr constructors whose function bodies are=default or= delete could have virtual base classes | such classes can neither have virtual base classes |
CWG 1595 | C++11 | constexpr delegating constructors required all involved constructors to beconstexpr | only requires the target constructor to beconstexpr |
CWG 1712 | C++14 | aconstexpr variable template was required to have all its declarations contain theconstexpr specifier[1] | not required anymore |
CWG 1911 | C++11 | constexpr constructors for non-literal types were not allowed | allowed in constant initialization |
CWG 2004 | C++11 | copy/move of a union with a mutable member was allowed in a constant expression | mutable variants disqualify implicit copy/move |
CWG 2022 | C++98 | whether equivalentconstexpr and non-constexpr function produce equal result might depend on whether copy elision is performed | assume that copy elision is always performed in constant expressions |
CWG 2163 | C++14 | labels were allowed inconstexpr functions even thoughgoto statements are prohibited | labels also prohibited |
CWG 2268 | C++11 | copy/move of a union with a mutable member was prohibited by the resolution ofCWG issue 2004 | allowed if the object is created within the constant expression |
CWG 2278 | C++98 | the resolution ofCWG issue 2022 was not implementable | assume that copy elision is never performed in constant expressions |
CWG 2531 | C++11 | a non-inline variable became inline if it is redeclared withconstexpr | the variable does not become inline |
constant expression | defines anexpression that can be evaluated at compile time |
consteval specifier(C++20) | specifies that a function is animmediate function, that is, every call to the function must be in a constant evaluation[edit] |
constinit specifier(C++20) | asserts that a variable has static initialization, i.e.zero initialization andconstant initialization[edit] |
C documentation forconstexpr |