constexpr — C++
What is constexpr?
constexpr (C++11) tells the compiler to evaluate an expression at compile time if possible. It applies to variables and functions. C++20 added consteval (compile-time only) and constinit (constant initialization).
constexpr Variables
Must be initialized with a constant expression. Examples:
constexpr int max_size = 100;
constexpr double pi = 3.14159265358979;
constexpr int arr_size = max_size * 2; // composed constexpr
constexpr Functions
Can be evaluated at compile time (if all arguments are constant expressions) or at runtime (if not). C++11 had a strict single-return-statement rule; C++14 relaxed it; C++20 allows virtual functions.
constexpr int square(int x) { return x * x; }
constexpr int s = square(5); // compile-time: s == 25
int n = 7;
int r = square(n); // runtime evaluation
constexpr if (C++17)
if constexpr selects a branch at compile time based on a constant expression. The discarded branch is not instantiated — this enables generic code without SFINAE tricks.
template <typename T>
auto process(T val) {
if constexpr (std::is_integral_v<T>) {
return val * 2;
} else {
return val + 0.5;
}
}
[!TIP]
if constexprreplaces many SFINAE patterns and tag dispatch tricks that were common before C++17.
consteval (C++20)
Functions marked consteval are immediate functions — they MUST be called at compile time. A runtime call is a compile error.
consteval int triple(int x) { return x * 3; }
constexpr int t = triple(4); // OK: compile-time
// int n = 5; triple(n); // ERROR: n is not constexpr
constinit (C++20)
constinit ensures a variable is constant-initialized (initialized at program start, not at first use). It does NOT make the variable constant — the value can change later. Prevents the “static initialization order fiasco.”
constinit int global_counter = 0; // constant-initialized
// global_counter = 42; // OK: not const
[!WARNING]
constinitonly guarantees the initialization is constant - the variable itself is still mutable unless also declaredconst.
Keyword Overview
flowchart TD A[“constexpr (C++11)”] –> B[“constexpr variable”] A –> C[“constexpr function”] A –> D[“if constexpr (C++17)”] A –> E[“consteval (C++20)”] A –> F[“constinit (C++20)”]
constexpr Function Evaluation
flowchart TD A[“Call constexpr function”] –> B{“All args constant?”} B –>|”Yes”| C[“Compile-time evaluation”] B –>|”No”| D[“Runtime evaluation”] C –> E[“Result embedded in binary”] D –> F[“Result computed at runtime”]
Summary Table
| Keyword | C++ Version | Purpose | Requirement |
|---|---|---|---|
constexpr var | C++11 | Compile-time constant | Must be initialized with constant expression |
constexpr fn | C++11 | Compile-time or runtime evaluation | Body must be constexpr-compatible |
if constexpr | C++17 | Compile-time branch selection | Condition must be constant expression |
consteval | C++20 | Force compile-time evaluation | Call site must be constant expression |
constinit | C++20 | Constant initialization guarantee | Must have constant initializer |