现代 C++ constexpr 特性演进:从 C++11 到 C++20
constexpr 是现代 C++ 中极具分量的关键字,它的核心目标是将计算从运行时转移到编译时,从而提升程序性能。随着标准的迭代,constexpr 的能力也在不断进化,逐渐模糊了编译期与运行时的界限。
一、C++11:严格限制下的常量表达式
在 C++11 标准中,constexpr 被引入用于指定常量表达式。编译器会在编译阶段尝试计算其值,若成功则直接替换,否则报错。
1. 基本概念
常量表达式的值在编译时期就能确定。用字面量或常量表达式初始化的 const 对象是常量表达式,但用变量初始化的 const 对象通常不是。
const int a = 1; // a 是常量表达式
const int b = a + 1; // b 是常量表达式
int c = 1;
const int d = c; // d 不是常量表达式,因为 c 的值可能在运行时改变
由于值在编译期已知,编译器可以直接优化替换。通过汇编对比可以发现,使用常量表达式的地方不会生成加载指令,而是直接嵌入立即数。
2. constexpr 修饰函数
constexpr 可以修饰函数,默认也是 inline 的。但在 C++11 中,对 constexpr 函数的要求极其严格:
- 参数和返回值必须是字面类型(如整型、浮点型、指针等)。
- 函数体只能包含一条 return 语句。
- 不能定义局部变量,不能有循环或条件语句。
- 必须有返回值。
注意: 只有当 constexpr 函数的结果被常量表达式接收时,才会触发编译期计算;否则它退化为普通函数。
constexpr int func1() { return 1; }
constexpr int func2(int x) { return x + 10; }
constexpr int func3(int n) { return n <= 1 ? : n * (n - ); }
{
a = ();
b = ();
c = ();
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << c << std::endl;
;
}





