constexpr is a C++ specifier that marks an entity as evaluable at Compile-Time. It can be applied to variables, functions, and if statements.
constexpr Variables
constexpr variables are essentially the C++ answer to the issues with C Macros. The compiler evaluates the code at Compile-Time but also with type, scope, operator precedence, etc. Whereas macros are literally dumb text substitution.
#define AREA 2 * 3 + 4 // expands to 2 * 3 + 4 = 10, not (2 * 3 + 4) = 10int x = AREA * 2; // 2 * 3 + 4 * 2 = 14, not 20constexpr int area = 2 * 3 + 4; // = 10, a real typed valueint y = area * 2; // = 20
constexpr Functions
A constexpr function can be evaluated at compile-time when given constant arguments, or at runtime otherwise.
constexpr int factorial(int n) { return (n <= 1) ? 1 : n * factorial(n - 1);}static_assert(factorial(5) == 120); // computed at compile-timeint x = factorial(runtime_value); // computed at runtime
Prior to constexpr, this functionality would have required recursive templating
And effectively, this is what is happening under the hood.
template <int N>struct Factorial { static constexpr int value = N * Factorial<N - 1>::value;};template <>struct Factorial<0> { static constexpr int value = 1;};static_assert(Factorial<5>::value == 120);
Prefer constexpr functions. They’re simpler and the compiler enforces the same guarantees.
if constexpr
if constexpr provides Compile-Time branching inside templates. The discarded branch is not instantiated, so it can contain code that would be ill-formed for the given type.