¶constexpr
constexpr用于表达常量表达式,可以作用到变量和函数上,表示该变量在编译期求值的,或者该函数可以在编译期求值(显然需要提供的函数参数都是常量表达式)。
const用于传达只读,constexpr用于传达常量。
1 | constexpr int f(int n) { // 这也是允许的,但显然只有传入的n是常量时才能编译期求值 |
¶consteval
consteval是一种局限的constexpr,只能作用到函数上,它强制该函数是完全编译期求值的,不能在运行时调用。
¶constinit
constinit仅与具有静态存储期(生命期等于整个程序)的变量的初始化有关。
具体有两种情况:
- 在编译期静态初始化,即初始值为常量表达式(constant initialization)
- 动态初始化,即运行时按执行流遇到的声明顺序计算
第2种方式存在初始化顺序不确定的问题(主要是全局变量)。
考虑两个编译单元中有两个全局变量A和B,而A的初始化依赖于B,但是A和B的初始化顺序是未定义的,一旦A先于B初始化,就会发生段错误。一种解决方式就是改用函数内的静态变量(即单例范式来替代裸的全局变量)。注意局部静态变量是在第一次函数调用时初始化的,因此如果存在依赖关系,要特别注意函数调用的顺序。
constinit作用在具有静态存储期的变量上,强制其在编译期初始化(即第1种方式)。constinit没有const语义,它修饰的变量仍然是可修改的,它与其它const是完全不同的(名字取得有误导性)。
事实上constexpr蕴含了constinit,但是多了const的限制。