std::is_constant_evaluated() 只能在 constexpr 或 consteval 函数中调用,返回 true 当且仅当当前调用处于常量求值路径,且其 if 分支内代码须满足常量表达式约束,不可用于 if constexpr。

std::is_constant_evaluated() 只能在 constexpr 函数里用
它根本不能出现在普通函数中,否则 GCC/Clang 会直接报错:call to non-constexpr function 'std::is_constant_evaluated'。这不是警告,是硬编译失败。
常见误操作:把 std::is_constant_evaluated() 拿去给一个非 constexpr 函数做“运行时环境探测”——语法上就不合法,连编译都过不去。
- 必须声明为
constexpr(或consteval)函数,才允许调用它 - 即使函数体里只有一行
return std::is_constant_evaluated();,也得加constexpr - lambda 中调用它,该 lambda 必须能参与常量求值(比如不捕获非常量变量、不调用非 constexpr 函数)
它返回 true 的唯一条件:当前这次调用真正在被常量求值
std::is_constant_evaluated() 不看函数是不是 constexpr,也不看参数是不是字面量,只看“这一轮执行是否被编译器选入常量求值路径”。哪怕函数声明为 constexpr,只要调用点不在常量表达式上下文(比如没用于数组长度、模板参数、static_assert 或 constinit 初始化),它就返回 false。
-
constexpr int x = safe_strlen("abc");→ 返回true(编译期求值) -
int y = safe_strlen(ptr);(ptr是运行时变量)→ 返回false,哪怕函数本身是constexpr - 在
consteval函数里调用它 → 一定返回true,因为consteval强制常量求值
编译期分支里不能写运行时专属代码
一旦进了 if (std::is_constant_evaluated()) { ... } 分支,里面所有语句都必须满足常量求值约束。写错一句,整个编译期路径就崩,但运行时调用却可能正常——这种不对称错误极难调试。
立即学习“C++免费学习笔记(深入)”;
- 禁止调用非
constexpr函数,比如std::strlen、std::printf、任何含new/malloc的逻辑 - 禁止读写静态/全局非常量变量(
static int counter;不行,static constexpr int N = 42;可以) - 禁止用
dynamic_cast、typeid、try/catch - 推荐只用基础循环、递归(深度受编译器限制)、字面量操作、
constexpr成员函数
别把它当 if constexpr 用
std::is_constant_evaluated() 返回的是运行时可变的 bool,不是编译期常量表达式,所以不能放进 if constexpr 条件里——if constexpr (std::is_constant_evaluated()) 是语法错误。
它的作用就是让你在同一个 constexpr 函数里,用普通 if 实现双路径:编译期走 A 路(受限但零开销),运行时走 B 路(自由但有成本)。真正容易被忽略的是:这两条路径的输入兼容性往往不同。比如编译期分支要求 const char* 必须指向字面量,而运行时分支可以接受任意指针;传错参数不会报编译错误,但会导致编译期分支静默失败(SFINAE 或 hard error),最终函数不可 constexpr。


















