C++23coreexpert
if consteval (C++23 Addition)
C++23 · Completing Modern · Compiler flag: -std=c++23
Explanation
Branch based on whether code is in a `consteval` context, simplifying compile-time logic.
Real-World Scenario
Use different code paths for compile-time vs. runtime in a math library.
Quick Snippet
snippet.cpp
if consteval { return 42; } else { return compute(); }Full Example
if_consteval.cpp
// CodeNebula - C++23 Example: if consteval
// Compile: g++ -std=c++23 -Wall -Wextra -o example if_consteval.cpp
// Note: Requires GCC 12+ / Clang 14+ / MSVC 19.33+
// 'if consteval' checks whether the current evaluation is a constant expression.
// It replaces std::is_constant_evaluated() with cleaner syntax.
// The true-branch is a consteval context; the false-branch is a runtime context.
#include <iostream>
#include <cmath>
// Different implementations for compile-time vs runtime
constexpr double my_sqrt(double x) {
if consteval {
// Compile-time: use a simple Newton's method approximation
if (x < 0) throw "negative input"; // constexpr-friendly error
double guess = x / 2.0;
for (int i = 0; i < 20; ++i)
guess = (guess + x / guess) / 2.0;
return guess;
} else {
// Runtime: use the optimized standard library version
return std::sqrt(x);
}
}
constexpr int compute(int x) {
if consteval {
// Compile-time: can use consteval-only functions
return x * x + 1; // Simple compile-time path
} else {
// Runtime path: may use non-constexpr operations
std::cout << " (computed at runtime)" << std::endl;
return x * x + 1;
}
}
// Negated form: if !consteval
constexpr int maybe_log(int value) {
if !consteval {
std::cout << " Logging value: " << value << std::endl;
}
return value * 2;
}
int main() {
std::cout << "=== if consteval ===" << std::endl;
// Compile-time evaluation
constexpr double sqrt2 = my_sqrt(2.0);
std::cout << "constexpr sqrt(2) = " << sqrt2 << std::endl;
// Runtime evaluation
double x = 2.0;
double rt_sqrt = my_sqrt(x);
std::cout << "runtime sqrt(2) = " << rt_sqrt << std::endl;
std::cout << "\n=== Compile-time vs runtime path ===" << std::endl;
constexpr int ct = compute(5);
std::cout << "constexpr compute(5) = " << ct << std::endl;
int val = 5;
int rt = compute(val);
std::cout << "runtime compute(5) = " << rt << std::endl;
std::cout << "\n=== if !consteval (negated form) ===" << std::endl;
constexpr int ct2 = maybe_log(10); // No logging at compile time
std::cout << "constexpr maybe_log(10) = " << ct2 << std::endl;
int v = 10;
int rt2 = maybe_log(v); // Logs at runtime
std::cout << "runtime maybe_log(10) = " << rt2 << std::endl;
return 0;
}
/*
Expected output:
=== if consteval ===
constexpr sqrt(2) = 1.41421
runtime sqrt(2) = 1.41421
=== Compile-time vs runtime path ===
constexpr compute(5) = 26
(computed at runtime)
runtime compute(5) = 26
=== if !consteval (negated form) ===
constexpr maybe_log(10) = 20
Logging value: 10
runtime maybe_log(10) = 20
*/
Run command
g++ -std=c++23 -Wall -Wextra -o example if_consteval.cpp