名前空間
変種
操作

定数初期化

提供: cppreference.com
< cpp‎ | language
2018年9月14日 (金) 20:36時点におけるMilkpot (トーク | 投稿記録)による版

 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定 (C++20未満)
noexcept 指定子 (C++11)
例外
名前空間
指定子
decltype (C++11)
auto (C++11)
alignas (C++11)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点
文字 - 文字列 - nullptr (C++11)
ユーザ定義 (C++11)
ユーティリティ
属性 (C++11)
typedef 宣言
型エイリアス宣言 (C++11)
キャスト
暗黙の変換 - 明示的な変換
static_cast - dynamic_cast
const_cast - reinterpret_cast
メモリ確保
クラス
クラス固有の関数特性
特別なメンバ関数
テンプレート
その他
 
 

静的変数の初期値をコンパイル時定数に初期化します。

目次

構文

static T & ref = constexpr; (1)
static T object = constexpr; (2)

説明

定数初期化は静的およびスレッドローカルなオブジェクトのゼロ初期化の後に (C++14未満)の代わりに (C++14以上)他のすべての初期化の前に行われます。 以下の変数のみが定数初期化されます。

1) 静的またはスレッドローカルな参照で、静的な glvalue、一時オブジェクト (またはその部分オブジェクト)、または関数に束縛され、その参照の初期化子内のすべての式 (暗黙の変換を含みます) が定数式の場合。
2) コンストラクタ呼び出しによって初期化されるクラス型の静的またはスレッドローカルなオブジェクトで、そのコンストラクタが constexpr であり、すべてのコンストラクタ引数 (暗黙の変換を含みます) が定数式であり、コンストラクタの初期化子リスト内の初期化子およびクラスメンバの brace-or-equal 初期化子が定数式のみを含む場合。
3) コンストラクタ呼び出しによって初期化されない静的またはスレッドローカルなオブジェクト (クラス型でなくても構いません) で、そのオブジェクトが値初期化される場合、またはその初期化子内のすべての式が定数式の場合。

定数初期化の効果は対応する初期化の効果と同じですが、静的またはスレッドローカルなオブジェクトのあらゆる他の初期化が始まるよりも前に完了することが保証されます。

ノート

コンパイラは、標準の初期化順序に従った場合と同じ値になることが保証できる場合は、他の静的およびスレッドローカルなオブジェクトを定数初期化を用いて初期化することが許されています。

#include <iostream>
#include <array>
 
struct S {
    static const int c;
};
const int d = 10 * S::c; // not a constant expression: S::c has no preceding
                         // initializer, this initialization happens after const
const int S::c = 5;      // constant initialization, guaranteed to happen first
int main()
{
    std::cout << "d = " << d << '\n';
    std::array<int, S::c> a1; // OK: S::c is a constant expression
//  std::array<int, d> a2;    // error: d is not a constant expression
}

出力:

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

関連項目