名前空間
変種
操作

定数初期化

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 

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

目次

[編集] 説明

定数初期化は以下のケースで実行されます。

  • POD型で静的記憶域期間を持つオブジェクトを定数式で初期化する場合。
(C++11まで)
  • 静的またはスレッド記憶域期間を持つ参照を初期化する場合で、以下の全ての条件が満たされる場合。
  • 初期化子に現れる各完全式(暗黙の変換を含む)が定数式であること。
  • 参照が以下のいずれかのエンティティに束縛されていること。
  • 静的記憶域期間を持つオブジェクトを指定するlvalue
  • 一時オブジェクト
  • 一時オブジェクトのサブオブジェクト
  • 関数
  • 静的またはスレッド記憶域期間を持つオブジェクトを初期化する場合で、以下のいずれかの条件が満たされる場合。
  • オブジェクトがコンストラクタ呼び出しによって初期化され、その初期化完全式が定数式である場合。ただし、オブジェクトとそのサブオブジェクト(リテラル型でないクラス型のオブジェクトであっても)に対してconstexprコンストラクタを呼び出す場合を除く。
  • それ以外の場合、オブジェクトが値初期化されているか、初期化子に現れるすべての完全式が定数式であること。
(C++11以降)
(C++17まで)
  • 静的またはスレッド記憶域期間を持つ変数または一時オブジェクトを、完全式定数式である初期化子によって初期化する場合。ただし、初期化されるエンティティがオブジェクトである場合、そのような初期化子は、オブジェクトとそのサブオブジェクト(リテラル型でないクラス型のオブジェクトであっても)に対してconstexprコンストラクタを呼び出す場合を除く。
(C++17以降)
(C++20まで)
(C++20以降)

定数初期化の効果は対応する初期化の効果と同じですが、静的またはスレッドローカル(C++11以降)オブジェクトの他の初期化が始まる前に完了することが保証されます。

[編集] 注記

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

定数初期化は通常、プログラムのランタイム環境の初期化の一部として、プログラムがメモリにロードされるときに発生します。

[編集]

#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 441 C++98 参照は定数初期化できなかった 定数初期化可能になった
CWG 1489 C++11 値初期化が定数初期化になるか不明だった
オブジェクトの定数初期化
できる
CWG 1747 C++11 関数への参照の束縛が定数初期化できなかった できる
CWG 1834 C++11 xvalueへの参照の束縛が定数初期化できなかった できる

[編集] 関連項目

English 日本語 中文(简体) 中文(繁體)