constexpr用于声明编译期可求值的常量或函数,如constexpr int val = square(5);在编译时计算结果,提升性能并减少运行时开销。

constexpr 是 C++11 引入、并在后续标准中不断强化的一个关键字,用于声明可以在编译期求值的常量表达式。合理使用 constexpr 能显著提升程序性能,减少运行时开销,并增强类型安全和代码可读性。
constexpr 基本用法
在变量或函数前加上 constexpr,表示其值在编译期就应能确定。
例如:定义一个编译期常量:
constexpr int square(int x) {
return x * x;
}
constexpr int val = square(5); // 编译期计算,val = 25
这个 square 函数在传入字面量或编译期已知值时,会直接在编译阶段完成计算,不会生成运行时调用指令。
立即学习“C++免费学习笔记(深入)”;
constexpr 函数的规则与限制
从 C++14 开始,constexpr 函数的限制大幅放宽。但仍需满足:在某些调用场景下,能于编译期求值。
主要要求包括:- 函数体不能包含异常抛出(如 throw)
- 不能使用未初始化的变量或动态内存(new/delete)
- 所有语句必须是编译期可执行的表达式
- 局部变量需初始化,且只能使用 constexpr 兼容的操作
C++14 允许 constexpr 函数内使用循环和条件分支,这让复杂逻辑也能参与编译期计算。
示例:编译期计算阶乘constexpr int factorial(int n) {
int result = 1;
for (int i = 2; i <= n; ++i) {
result *= i;
}
return result;
}
constexpr int fact5 = factorial(5); // 编译期得出 120
constexpr 与模板结合实现元编程
结合模板,constexpr 可替代部分模板元编程(TMP),写出更直观的编译期逻辑。
比如:编译期判断是否为质数constexpr bool is_prime(int n) {
if (n <= 1) return false;
for (int i = 2; i * i <= n; ++i) {
if (n % i == 0) return false;
}
return true;
}
static_assert(is_prime(17), "17 should be prime");
这里 static_assert 验证编译期断言,若表达式不成立则编译失败。
性能优势与应用场景
constexpr 的最大优势是将计算从运行时转移到编译期,带来以下好处:
- 减少运行时 CPU 开销,尤其对频繁调用的数学计算
- 允许在数组大小、模板参数等需要常量表达式的上下文中使用计算结果
- 提升代码安全性,避免运行时不可控的副作用
- 支持编译期查表,例如预计算 sin/cos 表、哈希值等
- 字符串哈希(如编译期计算字符串的 FNV-1a 哈希)
- 配置常量(如单位换算系数、物理常数)
- 容器大小(如 std::array
中的 N) - 策略选择(通过编译期条件决定行为)
基本上就这些。只要表达式能在编译期确定,就尽量用 constexpr,让编译器帮你“提前干活”,程序更快更稳。










