std::is_constant_evaluated() 是高性能几何库双模实现的强制分界线,用于区分编译期与运行时路径:normalize需避免非constexpr sqrt、rotation_matrix需用字面量角度匹配预置矩阵、aabb_tree_build输入必须为constexpr array,且返回值是否进编译期取决于调用点上下文。

std::is_constant_evaluated() 不是锦上添花的优化开关,而是高性能几何运算库中双模实现的**强制分界线**。不加它,normalize、rotation_matrix、aabb_tree_build 这类函数要么编译失败,要么在 constexpr 上下文中静默退化为低效运行时路径——结果是单位向量没折叠、旋转矩阵没内联、静态场景仍做递归构建。
为什么 normalize 必须用 std::is_constant_evaluated() 分支
向量归一化 v / sqrt(x*x + y*y + z*z) 在编译期已知长度时应直接简化为比例系数(如 {3,4,0} → {0.6, 0.8, 0}),但 std::sqrt 在 C++20 及之前不是 constexpr 函数。
- 混写
return v / std::sqrt(len2);在 constexpr 函数里 → GCC/Clang 直接报 “call to non-constexpr function” - 只写运行时逻辑 →
constexpr vec3 v = normalize({3, 4, 0});编译失败,失去常量折叠能力 - 中间变量
len2必须声明为constexpr double len2 = x*x + y*y + z*z;,否则编译器无法保证其可常量折叠 - 编译期分支里不能依赖运行时初始化,也不能调用任何非 constexpr 数学函数
rotation_matrix 中绕固定角度构造为何不能调用 std::sin/std::cos
绕 π/2、π 等特殊角度的旋转矩阵,在编译期应直接返回字面量 std::array;但 std::sin 和 std::cos 在绝大多数标准下都不是 constexpr 函数。
- 在
if constexpr (std::is_constant_evaluated())分支里写std::sin(angle)→ 编译失败,错误指向该行,而非 if 判断本身 - 必须用
if constexpr (angle == 1.5707963267948966)这类字面量比较,匹配后返回预置constexpr std::array - 运行时分支才可自由调用
std::sin(angle)、std::cos(angle)并填充std::array - 禁止在编译期分支中定义或引用
std::vector缓存表——只要代码存在,就违反 constexpr 约束
aabb_tree_build 的输入必须是 constexpr std::array 而非 const std::vector&
静态场景的包围盒树若在编译期已知几何体集合,整个层级结构可完全展开并剔除空节点;否则必须运行时递归构建。这个差异完全取决于输入是否能参与常量求值。
-
const std::vector即使内容不变,也无法触发编译期路径——& std::is_constant_evaluated()对它永远返回false - 输入必须作为模板参数或
constexpr std::array传入,才能让编译器判定为常量表达式上下文 - 编译期分支禁止任何动态内存操作:不能
new节点,不能调用std::vector::push_back,连取局部变量地址都受限 - 查表逻辑可放编译期分支,但表本身必须是
constexpr std::array,且索引计算全程可常量折叠
最容易被忽略的真相:返回值不看函数,而看调用点
std::is_constant_evaluated() 的返回值不取决于函数怎么写,而取决于“这次调用是否被上下文明确要求常量表达式”。这导致大量看似合理的调用实际进不了编译期分支。
-
int x = normalize(v);→ 必为false,哪怕v是字面量 -
const int y = normalize(v);→const不等于constexpr,标准不要求走编译期 - 唯一可靠验证方式只有:
static_assert(normalize(v) == expected);或int arr[normalize(v)]; - 跨平台项目应以 Clang 行为为底线——它比 GCC 更保守,某些 GCC 版本会在
constinit初始化中激进尝试常量求值,Clang 则直接拒绝
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











