Non-Profit, International

Spirit unsterblich.

constexpr,constinit 和 consteval

字数统计:1090 blog

C++11 中增加了关键字 constexpr,C++20 中增加了关键字 constinitconsteval。其中 constexpr 用于声明常量表达式,consteval 确保常量求值,constinit 用于静态初始化。

constexpr

constexpr 用于声明常量表达式:一个函数或者一个变量如果是 constexpr 的,那么代表其可以用于常量求值语境(在编译期进行计算)。例如用于模板参数或者数组下标。

声明为 constexpr 的函数也可以非常量使用,constexpr 声明只代表其具有常量求值的可能性。

如果想真正做到常量求值,需要保证所有值都是经由常量表达式计算而来的。

C++ Reference 上对函数何时能声明为 constexpr 有详细的描述:constexpr

consteval

由于 constexpr 函数可用于非常量使用,此时编译器可能会忽略 constexpr 修饰,产生一个运行期函数调用,而 consteval 修饰的函数则一定确保被常量使用,从而使得调用点一定获得一个常量,保证没有运行时函数调用。

constinit

constinit 说明符声明拥有静态或线程存储期的变量。若变量以 constinit 声明,则其初始化声明必须应用 constinit

实际上这就是强制一个静态储存期的变量必须被静态初始化,而不是在其他地方进行动态初始化,使得其在声明位置一定得到初始化。

constexpr 强制对象必须拥有静态初始化和常量析构,并使对象有 const 限定,然而 constinit 不强制常量析构和 const 限定。结果是拥有 constexpr 构造函数且无 constexpr 析构函数的类型(例如 std::shared_ptr<T> )的对象可能可以用 constinit ,但不能用 constexpr 声明。

参考:

若无特殊声明,本文以 CC BY-SA 3.0 许可协议 提供。