现代 C++ 新特性 constexpr:从 C++11 到 C++20 的演进
现代 C++ 标准不断演进,其中 constexpr 关键字的引入和发展尤为关键。它允许我们在编译阶段完成计算,从而将部分运行时的开销转移到编译期,提升程序性能。下面我们来梳理它在不同版本中的变化。
常量表达式与 constexpr 概念
常量表达式指的是值不变且能在编译期计算出结果的表达式。用字面量或常量表达式初始化的 const 对象属于常量表达式,但用变量初始化的则不是。
const int a = 1; // a 是常量表达式
const int b = a + 1; // b 是常量表达式
int c = 1; // c 不是
const int d = c; // d 不是,因为 c 的值可能在编译期不确定
由于编译器能提前确定这些值,可以直接替换,汇编层面能看到优化效果。
C++11 引入了 constexpr,用于指定常量表达式。它可以修饰变量,但要求必须是常量表达式且用常量初始化。

对于指针,constexpr 修饰的是指针本身(顶层 const)。这里顺便提一下 const 的分类:顶层 const 指对象本身不可变,底层 const 指指向的对象不可变。
constexpr 修饰函数
在 C++11 中,constexpr 函数默认是 inline 的,编译器会在编译期执行计算。但这带来了严格的限制:
- 参数和返回值必须是字面类型(如整型、浮点型、指针等)。
- 函数体只能包含一条
return语句。 - 不能定义局部变量,不能有循环或条件语句。
- 必须有返回值,且为常量表达式。
只有当结果被常量表达式接收时,才会触发编译期优化。否则它就像普通函数一样在运行时调用。
constexpr int func1() { return 1; }
constexpr int func2( x) { x + ; }
{ n <= ? : n * (n - ); }
{
a = ();
b = ();
c = ();
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << c << std::endl;
;
}


