命名空间
变体
操作

constinit 说明符 (自 C++20 起)

来自 cppreference.com
< cpp‎ | language
 
 
C++ 语言
 
 

内容

[编辑] 解释

constinit 说明符声明一个具有静态或线程 存储持续时间 的变量。如果一个变量用 constinit 声明,则其 初始化声明 必须使用 constinit 应用。如果用 constinit 声明的变量具有 动态初始化(即使它 作为静态初始化执行),则程序格式错误。如果没有 constinit 声明在初始化声明点可达,则程序格式错误,不需要诊断。

constinit 不能与 constexpr 结合使用。当声明的变量为引用时,constinit 等效于 constexpr。当声明的变量为对象时,constexpr 要求该对象必须具有静态初始化和常量析构,并使该对象为 const 限定,但是,constinit 不要求常量析构和 const 限定。因此,具有 constexpr 构造函数且没有 constexpr 析构函数(例如 std::shared_ptr<T>)的类型的对象可以使用 constinit 声明,但不能使用 constexpr

const char* g() { return "dynamic initialization"; }
constexpr const char* f(bool p) { return p ? "constant initializer" : g(); }
 
constinit const char* c = f(true);     // OK
// constinit const char* d = f(false); // error

constinit 也可以在非初始化声明中使用,以告诉编译器 thread_local 变量已初始化, 减少隐藏保护变量产生的开销

extern thread_local constinit int x;
int f() { return x; } // no check of a guard variable needed

[编辑] 说明

功能测试宏 标准 功能
__cpp_constinit 201907L (C++20) constinit

[编辑] 关键字

constinit

[编辑] 示例

#include <cassert>
 
constexpr int square(int i)
{
    return i * i;
}
 
int twice(int i)
{
    return i + i;
}
 
constinit int sq = square(2); // OK: init is done at compile time
// constinit int x_x = twice(2); // Error: compile time initializer required
 
int square_4_gen()
{
    static constinit int pow = square(4);
 
    // constinit int prev = pow; // Error: 'constinit' can only be applied to a
                                 // variable with static or thread storage duration
    int prev = pow;
    pow = pow * pow;
    return prev;
}
 
int main()
{
    assert(sq == 4);
    sq = twice(1); // Unlike constexpr this value can be changed later at runtime
    assert(sq == 2);
 
    assert(square_4_gen() == 16);
    assert(square_4_gen() == 256);
    assert(square_4_gen() == 65536);
}

[编辑] 缺陷报告

以下行为更改的缺陷报告被追溯应用到之前发布的 C++ 标准。

DR 应用于 已发布的行为 正确行为
CWG 2543 C++20 如果使用 constinit 声明的变量
在静态初始化期间动态初始化
程序在这种情况下是不-
格式良好的

[编辑] 参见

consteval 指定符(C++20) 指定函数为 *立即函数*,也就是说,对函数的每次调用都必须在常量评估中[编辑]
constexpr 指定符(C++11) 指定变量或函数的值可以在编译时计算[编辑]
常量表达式 定义可以在编译时计算的 表达式
常量初始化 静态 变量的初始值设置为编译时常量
零初始化 将对象的初始值设置为零