std::is_constant_evaluated()用于C++20中区分编译期与运行期求值,需GCC 10+/Clang 11+/MSVC 19.30+并启用-std=c++20,头文件为<type_traits>,可在constexpr函数中根据返回值分流逻辑。

在 C++20 中,当需要同一段逻辑既能在编译期求值、又能在运行期执行时,手动写两套分支容易出错且难以维护;std::is_constant_evaluated() 能让编译器在 constexpr 上下文中自动识别当前是否处于常量求值阶段,配合 consteval 函数可精准剥离运行期不可用的路径,避免模板膨胀与冗余代码生成。
确认编译器支持并启用 C++20
使用 GCC 10+、Clang 11+ 或 MSVC 19.30+,并在编译时显式指定 -std=c++20(GCC/Clang)或 /std:c++20(MSVC)。旧版标准下该函数未定义,链接会失败。
检查头文件包含:#include <type_traits> —— 这是唯一必需头文件,无需额外引入 <concepts> 或 <utility>。
基础用法:用 is_constant_evaluated() 分流逻辑
在 constexpr 函数中调用 std::is_constant_evaluated(),返回 true 表示当前正被编译器用于常量求值(如模板实参、数组大小、static_assert 表达式),否则为 false。
立即学习“C++免费学习笔记(深入)”;
写一个计算平方的函数,编译期走查表(无分支开销),运行期走乘法(避免大数组占用):
constexpr int square(int x) {<br> if (std::is_constant_evaluated()) {<br> // 编译期:用 constexpr 数组查表(仅限小范围)<br> constexpr int table[11] = {0,1,4,9,16,25,36,49,64,81,100};<br> return (x >= 0 && x <= 10) ? table[x] : x * x;<br> } else {<br> // 运行期:直接乘法,无栈上大数组<br> return x * x;<br> }<br>}
注意:table 必须声明为 constexpr,否则在常量求值路径中初始化非法;若去掉 constexpr 修饰,编译将报错 call to non-constexpr function。
进阶配合:用 consteval 强制编译期求值 + is_constant_evaluated 防误用
方法一:将纯编译期逻辑封装为 consteval 函数,再由主函数按需调用
第一步:定义 consteval 版本,只接受字面量参数,确保无法在运行期调用
consteval int compile_time_square(int x) { return x * x; }
第二步:主函数中用 std::is_constant_evaluated() 判断是否应调用它
constexpr int smart_square(int x) {<br> if (std::is_constant_evaluated()) {<br> return compile_time_square(x); // ✅ 此处调用合法<br> } else {<br> return x * x; // ✅ 运行期安全回退<br> }<br>}
第三步:验证行为——int arr[smart_square(5)]; 触发常量求值路径;int y = smart_square(rand() % 10); 走 else 分支。若错误地在运行期调用 compile_time_square(x),编译器立即报错,【这是 consteval 的强制约束,不是运行时检查】。
方法二:直接在 consteval 函数内部调用 is_constant_evaluated()?不行——consteval 函数体内调用该函数永远返回 true,失去分流意义,编译器会警告或忽略该分支。



















