if consteval
if consteval checks whether the current evaluation context is a manifestly constant-evaluated context, meaning a context where the compiler is required to produce a compile-time constant (e.g., initializing a constexpr variable, evaluating a static_assert, or computing a template argument). It was added in C++23 and formally called a consteval if statement: “The statement that begins with if consteval is known as the consteval if statement…”. This makes it useful inside constexpr functions, functions that live a double life (compile time and runtime), where you want different implementations for each:
constexpr int fast_sqrt(int n) {
if consteval {
// compile-time: must be constexpr-friendly, no intrinsics
int i = 0;
while (i * i <= n) ++i;
return i - 1;
} else {
// runtime: use optimized hardware path
return static_cast<int>(__builtin_sqrt(n));
}
}
constexpr int x = fast_sqrt(49); invokes the if consteval branch. int x = fast_sqrt(n); with a runtime n takes the else branch.
Note that if consteval takes no condition. It does not test whether a specific expression is a compile-time constant. To verify that, use static_assert or assign to a constexpr variable instead.
template<int N>
struct square : std::integral_constant<int, N * N> {};
template<int N>
inline constexpr int square_v = square<N>::value;
// wrong: if consteval doesn't take an expression
if consteval (square_v<23>) { }
// do this instead
static_assert(square_v<23> == 529);
// or this
constexpr int x = square_v<23>;