1. Problem It Solves
One constexpr function sometimes needs different code during constant evaluation and runtime evaluation. C++23 provides a direct, readable test of that evaluation context. The goal is to make the relevant rule visible in code instead of relying on an assumption about what “C++23 support” means.
2. Prerequisites
Day 6: runtime execution versus stored coroutine state.
Earlier knowledge of
constexprfunctions and ordinaryif.
3. Core Idea
The compiler has two rooms: compile time and runtime. if consteval asks which room is currently evaluating this call, not whether the function was declared constexpr. Read the syntax from left to right, identify the value, object, or range being transformed, and then check its resulting type, lifetime, or ownership. Standardization and implementation are separate: a C++23 mode may still lack one library component, so a feature-test macro is part of responsible portable use.
4. Minimal Syntax
if consteval { return compile_path; } else { return runtime_path; }5. How It Works
The sample builds the smallest expression or object needed for
if constevalandif !consteval.It calls the same function once in a constant expression and once at runtime. The compiler and library apply the relevant rule before the program observes the result.
The program prints or checks two deliberately different values that reveal the selected branch, making the important behavior easy to verify.
6. Common Mistakes
Replacing this with
std::is_constant_evaluated()inside a normalifcan make immediate-function calls ill-formed in cases whereif constevalis designed to work.Enabling C++23 mode without checking the relevant feature macro may select code that the installed compiler or standard library does not implement yet.
7. When to Use It
Use it when the task involves a shared API that needs a legal compile-time implementation and a different efficient runtime implementation.
Avoid it when the task involves using it as a test for whether an argument is known at compile time outside constant evaluation.
8. Simple Example
A checksum function uses a simple compile-time path and a platform-optimized runtime path behind one interface. The downloadable program keeps the data fixed so the output can be compared without entering input.
Complete sample code
Source file
cpp23/07_if_consteval/main.cpp
#include <iostream>
constexpr int scale(int value) {
if consteval {
return value * 2;
} else {
return value * 3;
}
}
constexpr int offset(int value) {
if !consteval {
return value + 10;
} else {
return value + 1;
}
}
int main() {
constexpr int compile_time = scale(4);
int input = 4;
std::cout << compile_time << ' ' << scale(input) << ' '
<< offset(input) << '\n';
}
9. Key Takeaways
Separate the language rule from compiler and library availability.
Keep lifetime, ownership, and deduced types visible when they affect correctness.
Prefer the smallest syntax that communicates the intent.
Guard facilities that are not yet uniformly implemented.
10. Self-Check Questions
Easy — What is the smallest syntax in Section 4, and what main job does it perform?
Medium — Read the sample program: which value, type, or branch is observed, and why?
Hard — In a
constexprfunction called with a literal but assigned to a non-constexprvariable, which branch is selected and why?