constinit
specifier
(since C++20)
| General topics | ||||||||||||||||
| Flow control | ||||||||||||||||
| Conditional execution statements | ||||||||||||||||
| Iteration statements (loops) | ||||||||||||||||
|
||||||||||||||||
| Jump statements | ||||||||||||||||
| Functions | ||||||||||||||||
| Function declaration | ||||||||||||||||
| Lambda function expression | ||||||||||||||||
inline
specifier
|
||||||||||||||||
| Dynamic exception specifications ( until C++17* ) | ||||||||||||||||
noexcept
specifier
(C++11)
|
||||||||||||||||
| Exceptions | ||||||||||||||||
| Namespaces | ||||||||||||||||
| Types | ||||||||||||||||
| Specifiers | ||||||||||||||||
|
||||||||||||||||
| Storage duration specifiers | ||||||||||||||||
| Initialization | ||||||||||||||||
| Expressions | ||||||||||||||||
| Alternative representations | ||||||||||||||||
| Literals | ||||||||||||||||
| Boolean - Integer - Floating-point | ||||||||||||||||
| Character - String - nullptr (C++11) | ||||||||||||||||
| User-defined (C++11) | ||||||||||||||||
| Utilities | ||||||||||||||||
| Attributes (C++11) | ||||||||||||||||
| Types | ||||||||||||||||
typedef
declaration
|
||||||||||||||||
| Type alias declaration (C++11) | ||||||||||||||||
| Casts | ||||||||||||||||
| Memory allocation | ||||||||||||||||
| Classes | ||||||||||||||||
| Class-specific function properties | ||||||||||||||||
|
||||||||||||||||
| Special member functions | ||||||||||||||||
|
||||||||||||||||
| Templates | ||||||||||||||||
| Miscellaneous | ||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
目次 |
説明
constinit 指定子は、静的またはスレッド ストレージ期間 を持つ変数を宣言します。
|
constinit 指定子は 構造化束縛 宣言にも適用できます。この場合、 constinit は宣言によって導入される 一意に名前付けされた変数 にも適用されます。 |
(C++26以降) |
変数が 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); // エラー
constinit は非初期化宣言でも使用でき、 thread_local 変数が既に初期化済みであることをコンパイラに伝えるために用いられます。これにより、 隠れたガード変数によるオーバーヘッドを削減 できます。
extern thread_local constinit int x; int f() { return x; } // ガード変数のチェックは不要
注記
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_constinit
|
201907L
|
(C++20) | constinit |
キーワード
例
#include <cassert> constexpr int square(int i) { return i * i; } int twice(int i) { return i + i; } constinit int sq = square(2); // OK: 初期化はコンパイル時に行われる // constinit int x_x = twice(2); // エラー: コンパイル時初期化子が必要 int square_4_gen() { static constinit int pow = square(4); // constinit int prev = pow; // エラー: constinitは静的またはスレッド記憶域期間を持つ変数にのみ適用可能 int prev = pow; pow = pow * pow; return prev; } int main() { assert(sq == 4); sq = twice(1); // constexprとは異なり、この値は後で実行時に変更可能 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)
|
変数または関数の値がコンパイル時に計算可能であることを指定する |
| 定数式 | コンパイル時に評価可能な 式 を定義する |
| 定数初期化 | 静的 変数の初期値をコンパイル時定数に設定する |
| ゼロ初期化 | オブジェクトの初期値をゼロに設定する |