定数初期化
提供: cppreference.com
静的変数の初期値をコンパイル時定数に初期化します。
構文
static T & ref = constexpr;
|
(1) | ||||||||
static T object = constexpr;
|
(2) | ||||||||
説明
定数初期化は静的およびスレッドローカルなオブジェクトのゼロ初期化の後に (C++14未満)の代わりに (C++14以上)他のすべての初期化の前に行われます。 以下の変数のみが定数初期化されます。
1) 静的またはスレッドローカルな参照で、静的な glvalue、一時オブジェクト (またはその部分オブジェクト)、または関数に束縛され、その参照の初期化子内のすべての式 (暗黙の変換を含みます) が定数式の場合。
2) コンストラクタ呼び出しによって初期化されるクラス型の静的またはスレッドローカルなオブジェクトで、そのコンストラクタが constexpr であり、すべてのコンストラクタ引数 (暗黙の変換を含みます) が定数式であり、コンストラクタの初期化子リスト内の初期化子およびクラスメンバの波括弧または等号の初期化子が定数式のみを含む場合。
3) コンストラクタ呼び出しによって初期化されない静的またはスレッドローカルなオブジェクト (クラス型でなくても構いません) で、そのオブジェクトが値初期化される場合、またはその初期化子内のすべての式が定数式の場合。
定数初期化の効果は対応する初期化の効果と同じですが、静的またはスレッドローカルなオブジェクトのあらゆる他の初期化が始まるよりも前に完了することが保証されます。
ノート
コンパイラは、標準の初期化順序に従った場合と同じ値になることが保証できる場合は、他の静的およびスレッドローカルなオブジェクトを定数初期化を用いて初期化することが許されています。
実際には、定数初期化はコンパイル時に行われ、事前計算されたオブジェクト表現がプログラムイメージの一部として (例えば .data セクションに) 格納されます。 変数が const であり定数初期化される場合、そのオブジェクト表現はプログラムイメージの読み込み専用セクション (例えば .rodata セクション) に格納されることがあります。
例
Run this code
#include <iostream>
#include <array>
struct S {
static const int c;
};
const int d = 10 * S::c; // 定数式ではありません。 S::c にはまだ初期化子がありません。
// この初期化は const の後に行われます。
const int S::c = 5; // 定数初期化。 最初に行われることが保証されます。
int main()
{
std::cout << "d = " << d << '\n';
std::array<int, S::c> a1; // OK、 S::c は定数式です。
// std::array<int, d> a2; // エラー、 d は定数式ではありません。
}
出力:
d = 50
欠陥報告
以下の動作変更欠陥報告は以前に発行された C++ 標準に遡って適用されました。
| DR | 適用先 | 発行時の動作 | 正しい動作 |
|---|---|---|---|
| CWG 2026 | C++14 | zero-init was specified to always occur first, even before constant-init | no zero-init if constant init applies |