名稱空間
變體
操作

constinit 說明符 (C++20 起)

來自 cppreference.com
< cpp‎ | 語言
 
 
C++ 語言
 
 

目錄

[編輯] 解釋

constinit 說明符宣告具有靜態或執行緒儲存期的變數。

constinit 說明符也可以應用於結構化繫結宣告。在這種情況下,constinit 也應用於宣告引入的唯一命名變數

(C++26 起)

如果變數宣告為 constinit,則其初始化宣告必須應用 constinit。如果宣告為 constinit 的變數具有動態初始化(即使它作為靜態初始化執行),則程式格式錯誤。

如果在初始化宣告點沒有可訪問的 constinit 宣告,則程式格式錯誤,無需診斷。

constinit 不能與 constexpr 一起使用。當宣告的變數是引用時,constinit 等同於 constexpr。當宣告的變數是物件時,constexpr 要求物件必須具有靜態初始化和常量銷燬,並使物件成為 const-qualified,然而,constinit 不要求常量銷燬和 const-qualification。因此,具有 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: initialization 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++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
CWG 2543 C++20 如果用 constinit 宣告的變數
作為靜態初始化的一部分進行動態初始化,則行為不明確
程式格式錯誤
在這種情況下,列舉是病態的

[編輯] 另請參閱

consteval 說明符(C++20) 指定函式為“即時函式”,即對該函式的每次呼叫都必須在常量求值中[編輯]
constexpr 說明符(C++11) 指定變數或函式的值可以在編譯時計算[編輯]
常量表達式 定義可在編譯時求值的表示式
常量初始化 靜態變數的初始值設定為編譯時常量
零初始化 將物件的初始值設定為零