在 C++20 之前,constexpr 已经让我们可以在编译期执行函数,计算常量。但随着标准的演进,constexpr 的功能被大幅扩展,几乎可以在编译期执行任何合法的 C++ 代码。本文将从语法、限制、典型应用以及性能影响四个方面,深入探讨 constexpr 的极限。
1. 语法演进
| 版本 | 关键特性 |
|---|---|
| C++11 | constexpr 函数只能包含一个返回语句、单条 return,并且不允许循环、递归(仅在递归深度有限时可行)。 |
| C++14 | 允许多条语句、循环、递归;但仅允许返回 constexpr 表达式。 |
| C++17 | 支持 if constexpr、三目运算符、以及 constexpr 的 throw。 |
| C++20 | 完全支持局部 static 变量、try/catch、模板变量、constexpr 的成员函数、operator new、以及 std::span 等常见库。 |
C++20 将 constexpr 的定义几乎等同于普通函数,只是对可执行代码进行了编译期可评估的约束。只要代码在编译期能被求值,就可以在 constexpr 上下文中使用。
2. 典型应用
2.1 计算阶乘
constexpr std::size_t factorial(std::size_t n) {
return n <= 1 ? 1 : n * factorial(n - 1);
}
在编译期计算 `factorial
()` 立即得到 3628800,无需运行时开销。 #### 2.2 类型安全的字符串拼接 “`cpp template constexpr std::array concat(const char (&a)[N], const char (&b)[M]) { std::array result{}; for (std::size_t i = 0; i