Namespaces
Variants

Constant initialization

From cppreference.net
C++ language
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
constexpr (C++11)
consteval (C++20)
constinit (C++20)
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

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

目次

説明

定数初期化 は以下の場合に実行されます:

  • 静的ストレージ期間を持つ POD type のオブジェクトをconstant expressionで初期化すること。
(C++11まで)
  • 静的またはスレッドストレージ期間を持つ参照の初期化で、以下の条件をすべて満たす場合:
  • 初期化子に現れる各 full-expression (暗黙の変換を含む)が constant expression であること。
  • 参照が以下のいずれかのエンティティに束縛されること:
  • 静的ストレージ期間を持つオブジェクトを指す左辺値
  • 一時オブジェクト
  • 一時オブジェクトの subobject
  • 関数
  • 静的またはスレッドストレージ期間を持つオブジェクトの初期化で、以下のいずれかの条件を満たす場合:
  • オブジェクトがコンストラクタ呼び出しによって初期化され、初期化のfull-expressionがconstant expressionであること(ただし、オブジェクトとそのsubobjectsの constexpr constructors を呼び出すことも可能)。
  • それ以外の場合、オブジェクトが value-initialized されるか、初期化子に現れるすべてのfull-expressionがconstant expressionであること。
(C++11以降)
(C++17まで)
  • 静的またはスレッドストレージ期間を持つ変数または一時オブジェクトを、 full-expression constant expression である初期化子で初期化すること(ただし、初期化されるエンティティがオブジェクトの場合、そのような初期化子はオブジェクトとその subobjects constexpr constructors を呼び出すことも可能)。
(C++17以降)
(C++20まで)
  • 静的またはスレッドストレージ期間を持つ変数 または一時オブジェクト (C++26まで) constant-initialized されること。
(C++20以降)

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

注記

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

定数初期化は通常、プログラムの実行時環境の初期化の一部として、プログラムがメモリにロードされる際に行われます。

#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 441 C++98 参照は定数初期化できなかった 定数初期化可能に変更
CWG 1489 C++11 値初期化が定数初期化となり得るか不明確だった 定数初期化となり得る
CWG 1747 C++11 関数への参照のバインドは定数初期化できなかった 定数初期化可能
CWG 1834 C++11 xvalueへの参照のバインドは定数初期化できなかった 定数初期化可能

関連項目