Namespaces
Variants

Constant expressions

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

コンパイル時に評価可能な expression を定義します。

このような式は、定数テンプレート引数、配列サイズ、およびその他の定数式を必要とする文脈で使用できます。例えば、

int n = 1;
std::array<int, n> a1;  // エラー: 「n」は定数式ではありません
const int cn = 2;
std::array<int, cn> a2; // OK: 「cn」は定数式です

目次

定義

以下の定数式カテゴリのいずれかに属する式は 定数式 です。

C++98 定数式カテゴリ

整数定数式 (C++98)

以下の場所では、C++は整数または列挙型の定数に評価される式を要求します:

以下のすべての条件を満たす式は 整数定数式 です:

  • 以下のエンティティのみを含む:
  • 算術型のリテラル
  • 列挙子
  • 以下のすべての条件を満たす変数または静的データメンバ:
  • const修飾されている
  • volatile修飾されていない
  • 整数型または列挙型である
  • 定数式で初期化されている
  • 浮動小数点リテラルを使用しない(整数または列挙型に明示的に変換された場合を除く)
  • 非整数型および非列挙型への変換を適用しない
  • 以下のエンティティを sizeof のオペランド以外で使用しない:
  • 関数
  • クラスオブジェクト
  • ポインタ
  • 参照
  • 代入演算子
  • インクリメント演算子
  • デクリメント演算子
  • 関数呼び出し演算子
  • コンマ演算子

その他の定数式カテゴリ

他の式は 定数初期化 の目的でのみ定数式と見なされます。このような定数式は以下のいずれかでなければなりません:

  • ヌルポインタ値 に評価される式
  • ヌルメンバポインタ値に評価される式
  • 算術定数式
  • アドレス定数式
  • 参照定数式
  • 完全オブジェクト型のアドレス定数式に整数定数式を加算または減算した式
  • メンバポインタ定数式

算術定数式 は、以下の例外を除いて整数定数式の要件を満たす式です:

  • 浮動小数点リテラルを明示的な変換なしで使用できる
  • 浮動小数点型への変換を適用できる

アドレス定数式 は、以下のすべての条件を満たすポインタ型の式です:

  • アドレス演算子の明示的な使用
  • ポインタ型の定数テンプレートパラメータの暗黙的な使用
  • 配列または関数型の式の使用
  • 式が関数を呼び出さない
  • 式が明示的なポインタ変換( dynamic_cast を除く)と以下の演算子を使用し、結果オブジェクトにアクセスしない:
  • 添字演算子
  • 間接演算子
  • アドレス演算子
  • メンバアクセス演算子
  • 添字演算子を使用する場合、そのオペランドの1つが整数定数式である

参照定数式 は、以下のすべての条件を満たす参照型の式です:

  • 参照が静的記憶域期間のオブジェクト、参照型の定数テンプレートパラメータ、または関数を指す。参照は非PODクラス型のメンバまたは基底クラスを指さない。
  • 式が関数を呼び出さない
  • 式が明示的な参照変換( dynamic_cast を除く)と以下の演算子を使用し、結果オブジェクトにアクセスしない:
  • 添字演算子
  • 間接演算子
  • アドレス演算子
  • メンバアクセス演算子
  • 添字演算子を使用する場合、そのオペランドの1つが整数定数式である

メンバポインタ定数式 は、修飾名にアドレス演算子を適用し、オプションで明示的なメンバポインタ変換を前置して作成されたメンバポインタ型の式です。

(C++11以前)

以下の式は総称して constant expressions (定数式)と呼ばれる:

  • 非ポインタ core constant expressions のprvalue
  • static storage duration を持つオブジェクトまたは関数を指すlvalue core constant expressions
  • 以下のいずれかの値に評価されるポインタ型のprvalue core constant expressions:
  • static storage durationを持つオブジェクトのアドレス
  • 関数のアドレス
  • null pointer value
(C++11以降)
(C++14まで)

以下のエンティティは 定数式の許可された結果 です:

  • 静的ストレージ期間を持つ一時オブジェクト
  • 静的ストレージ期間を持ち、値が以下にリストする制約を満たす非一時オブジェクト
  • immediate (C++20以降) 関数

定数式 とは、定数式の許可された結果であるエンティティを参照するglvalue コア定数式 であるか、または値が以下の制約を満たすprvalueコア定数式のいずれかです:

  • 値がクラス型のオブジェクトである場合、参照型の非静的データメンバーはそれぞれ、定数式の許可された結果であるエンティティを参照する。
  • 値が スカラ型 のオブジェクトである場合、 不定 値を持たない。
  • 値が ポインタ型 である場合、以下の値のいずれかである:
  • 静的ストレージ期間を持つオブジェクトのアドレス
  • 静的ストレージ期間を持つオブジェクトの終端を過ぎたアドレス
  • 非immediate (C++20以降) 関数のアドレス
  • ヌルポインタ値
  • 値がメンバー関数へのポインタ型である場合、immediate関数を指定しない。
(C++20以降)
  • 値がクラス型または配列型のオブジェクトである場合、各サブオブジェクトは値についてこれらの制約を満たす。
(C++14以降)
(C++26まで)

定数式 は、オブジェクトまたは非 即時関数 を参照するglvalue コア定数式 、またはその値が以下の制約を満たすprvalueコア定数式のいずれかである:

(C++26以降)

式が定数式かどうかを判定する際、 copy elision は実行されないものと仮定されます。

C++98における定数式の定義は折りたたみボックス内に完全に含まれています。以下の説明はC++11以降のC++バージョンに適用されます。

リテラル型

以下の型はまとめて literal types と呼ばれます:

  • これは trivial destructor (until C++20) constexpr destructor (since C++20) を持ちます。
  • すべての非静的non-variantデータメンバと基底クラスが非volatileリテラル型です。
  • 以下のいずれかの型です:
(C++17以降)
  • 以下のいずれかの条件を満たす 集成体 共用体型:
  • バリアントメンバーを持たない
  • 非volatileリテラル型のバリアントメンバーを少なくとも1つ持つ
  • 非共用体の集成体型で、その各 匿名共用体 メンバーが以下のいずれかの条件を満たすもの:
  • バリアントメンバーを持たない
  • 非volatileリテラル型のバリアントメンバーを少なくとも1つ持つ
  • コピーコンストラクタまたはムーブコンストラクタではない constexpr コンストラクタ(テンプレート)を少なくとも1つ持つ型

リテラル型のオブジェクトのみが定数式内で作成できます。

コア定数式

core constant expression は、以下の言語構成のいずれかを評価 しない 式の評価のことです:

言語構成要素 バージョン 論文
this ポインタ、ただし式の一部として評価されている constexpr 関数 内、または暗黙的・明示的なクラスメンバアクセス式に現れる場合を除く N2235
静的またはスレッド ストレージ期間 を持つ ブロック変数 の宣言を通り抜ける制御フローで、その変数が 定数式で使用可能でない 場合 (C++23以降) P2242R3
  1. a function call expression that calls a function (or a constructor) that is not declared constexpr
    constexpr int n = std::numeric_limits<int>::max(); // OK: max() は constexpr
    constexpr int m = std::time(nullptr); // エラー: std::time() は constexpr ではない
  2. a function call to a constexpr function which is declared, but not defined
  3. a function call to a constexpr function/constructor template instantiation where the instantiation fails to satisfy constexpr関数/コンストラクタ requirements.
  4. a function call to a constexpr virtual function, invoked on an object whose dynamic type is constexpr-unknown
  5. an expression that would exceed the implementation-defined limits
  6. an expression whose evaluation leads to any form of core language undefined または誤った (C++26以降) behavior, except for any potential undefined behavior introduced by 標準属性 .
    constexpr double d1 = 2.0 / 1.0; // OK
    constexpr double d2 = 2.0 / 0.0; // エラー: 未定義
    constexpr int n = std::numeric_limits<int>::max() + 1; // エラー: オーバーフロー
    int x, y, z[30];
    constexpr auto e1 = &y - &x;        // エラー: 未定義
    constexpr auto e2 = &z[20] - &z[3]; // OK
    constexpr std::bitset<2> a; 
    constexpr bool b = a[2]; // 未定義動作、検出されるかどうかは未指定
  7. (C++17まで) a ラムダ式
  8. an lvalue-to-rvalue 暗黙の変換 unless applied to...
    1. (possibly cv-qualified) 型の glvalue である std::nullptr_t
    2. 定数式で使用可能なオブジェクトを指す、非 volatile リテラル型の glvalue usable in constant expressions
      int main()
      {
          const std::size_t tabsize = 50;
          int tab[tabsize]; // OK: tabsize is a constant expression
                            // because tabsize is usable in constant expressions
                            // because it has const-qualified integral type, and
                            // its initializer is a constant initializer
          std::size_t n = 50;
          const std::size_t sz = n;
          int tab2[sz]; // Error: sz is not a constant expression
                        // because sz is not usable in constant expressions
                        // because its initializer was not a constant initializer
      }
    3. この式の評価内で生存期間が開始された非 volatile オブジェクトを参照する、非 volatile リテラル型の glvalue
  9. an lvalue-to-rvalue 暗黙の変換 or modification applied to a non-active member of a union or its subobject (even if it shares a common initial sequence with the active member)
  10. an lvalue-to-rvalue implicit conversion on an object 値が不定である
  11. an invocation of implicit copy/move constructor/assignment for a union whose active member is mutable (if any), with lifetime beginning outside the evaluation of this expression
  12. (C++20まで) an assignment expression that would change the active member of a union
  13. conversion from voidへの void ポインタ to a pointer-to-object type T* ポインタがヌルポインタ値を保持しているか、またはその型が similar であるオブジェクトを指していない限り T (since C++26)
  14. dynamic_cast オペランドがconstexpr-unknownな動的型を持つオブジェクトを参照するglvalueである (C++20以降)
  15. reinterpret_cast
  16. (C++20まで) pseudo-destructor call
  17. (C++14まで) an increment or a decrement operator
  18. (C++14以降) modification of an object, unless the object has non-volatile literal type and its lifetime began within the evaluation of the expression
    constexpr int incr(int& n)
    {
        return ++n;
    }
    constexpr int g(int k)
    {
        constexpr int x = incr(k); // エラー: incr(k) はコア定数式ではない
                                   // k の寿命が incr(k) 式の外側で
                                   // 始まっているため
        return x;
    }
    constexpr int h(int k)
    {
        int x = incr(k); // OK: x はコア定数式で初期化される
                         // 必要はない
        return x;
    }
    constexpr int y = h(1); // OK: y を値 2 で初期化する
                            // h(1) はコア定数式である。なぜなら
                            // k の寿命が式 h(1) の内側で始まるため
  19. (C++20以降) a destructor call or pseudo destructor call for an object whose lifetime did not begin within the evaluation of this expression
  20. a typeid expression applied to a glvalue of polymorphic type そのglvalueがconstexpr-unknownな動的型を持つオブジェクトを参照している場合 (C++20以降)
  21. a new expression 以下のいずれかの条件が満たされない限り: (C++20以降)
    • 選択された allocation function は置換可能なグローバルな割り当て関数であり、割り当てられたストレージはこの式の評価内で解放される。
    (C++20以降)
    • 選択された割り当て関数は割り当て型 T を持つ非割り当て形式であり、配置引数が以下のすべての条件を満たす:
    • それが指すもの:
    • T が配列型でない場合、 T と類似の型を持つオブジェクト、または
    • T が配列型の場合、 T と類似の型を持つオブジェクトの最初の要素
    • それが指すストレージの存続期間がこの式の評価内で開始されたもの
    (C++26以降)
  22. a delete この式の評価内で割り当てられた記憶領域を解放しない限り (C++20以降)
  23. (C++20以降) Coroutines: an await式 or a yield式
  24. (C++20以降) a 三方比較 when the result is unspecified
  25. an equality or relational operator whose result is unspecified
  26. (C++14まで) an assignment or a compound assignment operator
  27. (C++26まで) throw式
  28. (C++26から) 例外オブジェクトの構築(ただし、例外オブジェクトと、 std::current_exception または std::rethrow_exception の呼び出しによって作成されるすべての暗黙的なコピーが、この式の評価内で破棄される場合を除く)
    constexpr void check(int i)
    {
        if (i < 0)
            throw i;
    }
    constexpr bool is_ok(int i)
    {
        try {
            check(i);
        } catch (...) {
            return false;
        }
        return true;
    }
    constexpr bool always_throw()
    {
        throw 12;
        return true;
    }
    static_assert(is_ok(5)); // OK
    static_assert(!is_ok(-1)); // C++26からOK
    static_assert(always_throw()); // エラー: キャッチされない例外
  29. asm宣言
  30. va_arg マクロの呼び出し
  31. goto
  32. dynamic_cast または typeid または new (C++26から) が例外をスローする場合 例外型の定義が到達可能でない場合 (C++26から)
  33. ラムダ式内での、 this またはそのラムダ外で定義された変数への参照(その参照がodr-useとなる場合)
    void g()
    {
        const int n = 0;
        constexpr int j = *&n; // OK: ラムダ式の外側
        [=]
        {
            constexpr int i = n;   // OK: 'n'はここではodr-usedされず、キャプチャもされない
            constexpr int j = *&n; // 不適格: '&n'は'n'のodr-useとなる
        };
    }

    odr-useがクロージャの関数呼び出しで行われる場合、それは this または外側の変数を参照しないことに注意(代わりにクロージャのデータメンバにアクセスするため)

    // OK: 'v' & 'm'はodr-usedされるが、ネストしたラムダ内の定数式では現れない
    // ネストしたラムダ内の定数式では現れない
    auto monad = [](auto v){ return [=]{ return v; }; };
    auto bind = [](auto m){ return [=](auto fvm){ return fvm(m()); }; };
    // 定数式評価中に作成された自動オブジェクトへのキャプチャはOK
    static_assert(bind(monad(2))(monad)() == monad(2)());
    (C++17から)

追加要件

E が上記のいずれにも該当しない場合でも、 E の評価が runtime-undefined behavior を引き起こす場合、 E がコア定数式であるかどうかは実装定義である。

E が上記のいずれも評価しない場合でも、 E の評価によって以下のいずれかが評価される場合、 E がコア定数式であるかどうかは未規定です:

  • 標準ライブラリにおける未定義動作の操作。
  • va_start マクロの呼び出し。

式がコア定数式であるかどうかを判定する目的において、 std:: allocator < T > のメンバ関数の本体の評価は、 T がリテラル型である場合には無視されます。

式がコア定数式であるかどうかを判定する目的において、トリビアルなコピー/ムーブコンストラクタまたはコピー/ムーブ代入演算子の呼び出しの評価は、 union のアクティブなメンバ(存在する場合)をコピー/ムーブすると見なされます。

式がコア定数式であるかどうかを判定する目的において、 構造化バインディング bd を名前とする識別子式の評価は以下の意味論を持つ:

  • bd が発明された参照 ref にバインドされたオブジェクトを参照する左辺値である場合、 ref が指定されたかのように振る舞う。
  • それ以外の場合、 bd が配列要素を名前とする場合、 e [ i ] の評価と同様に振る舞う。ここで e は構造化バインディング宣言の初期化子から初期化された変数の名前であり、 i bd によって参照される要素のインデックスである。
  • それ以外の場合、 bd がクラスメンバを名前とする場合、 e. m の評価と同様に振る舞う。ここで e は構造化バインディング宣言の初期化子から初期化された変数の名前であり、 m bd によって参照されるメンバの名前である。
(C++26以降)

式をコア定数式として評価する際、すべての識別子式および * this の使用で、そのオブジェクトまたは参照の寿命が式の評価の外側で始まったものを参照するものは、そのオブジェクトまたは参照の特定のインスタンスを参照するものとして扱われ、その寿命およびすべての部分オブジェクト(すべての共用体メンバーを含む)の寿命が定数評価全体を含むものとみなされます。

  • そのようなオブジェクトが 定数式で使用可能 でない場合 (C++20以降) 、そのオブジェクトの動的型は constexpr-unknown となる。
  • そのような参照が 定数式で使用可能でない場合 (C++20以降) 、その参照は、参照される型の不特定オブジェクトにバインドされているものとして扱われる。このオブジェクトとそのすべての部分オブジェクトの寿命は定数評価全体を含み、動的型はconstexpr-unknownである。

整数定数式

整数定数式 は、整数型またはスコープなし列挙型の式がprvalueに暗黙的に変換されたもので、変換された式がコア定数式であるものを指します。

クラス型の式が整数定数式が期待される文脈で使用される場合、その式は 文脈に応じた暗黙変換 によって整数型またはスコープなし列挙型へ変換されます。

変換済み定数式

変換済み定数式 は、型 T への 暗黙変換 が施された式であり、変換後の式が定数式であり、かつ暗黙変換シーケンスが以下のみを含む場合を指します:

(C++17以降)

また、いずれかの reference binding が行われる場合、それは direct binding のみとなります。

以下のコンテキストでは変換された定数式が必要です:

(C++14以降)
(C++26以降)

bool の文脈的に変換された定数式 は、 bool へ文脈的に変換された 式であり、変換後の式が定数式であり、変換シーケンスが上記の変換のみを含むものです。

以下の文脈では、型 bool の文脈的に変換された定数式が必要です:

(C++23まで)
(C++17以降)
(C++23まで)
(C++20以降)


構成要素

オブジェクト obj 構成値 は以下のように定義される:

オブジェクト obj 構成参照 は以下の参照を含む:

変数 var 構成値 構成参照 は以下のように定義される:

  • var がオブジェクトを宣言する場合、構成値と構成参照はそのオブジェクトの構成値と構成参照である。
  • var が参照を宣言する場合、構成参照はその参照である。

変数 var の任意の構成参照 ref について、 ref が一時オブジェクトまたはその部分オブジェクトにバインドされており、その生存期間が ref 延長 されている場合、その一時オブジェクトの構成値と構成参照も再帰的に var の構成値と構成参照となる。

constexpr表現可能なエンティティ

静的記憶域期間を持つオブジェクトは、プログラム内の任意の時点で constexpr参照可能 である。

自動記憶域期間を持つオブジェクト obj は、点 P から constexpr参照可能 であるとは、変数 var を囲む最小スコープと P を囲む最小スコープが同じ関数パラメータスコープであり、かつ requires のパラメータリストに関連付けられていない場合である。ここで var obj の完全オブジェクトに対応する変数、または obj の生存期間が 延長 されている変数である。

オブジェクトまたは参照 x が点 P constexpr表現可能 であるとは、以下の条件がすべて満たされる場合である:

  • x の各構成値がオブジェクト obj を指す場合、 obj P からconstexpr参照可能である。
  • x の各構成値がオブジェクト obj を超えて指す場合、 obj P からconstexpr参照可能である。
  • x の各構成参照がオブジェクト obj を参照する場合、 obj P からconstexpr参照可能である。
(C++26以降)

定数初期化されたエンティティ

変数または一時オブジェクト obj は、以下の条件をすべて満たす場合に 定数初期化 される:

  • 初期化子を持つか、その型が const-default-constructible である。
  • その初期化の 完全式 は、定数式を要求する文脈における定数式である。ただし、 obj がオブジェクトの場合、その完全式は obj およびその部分オブジェクトに対する constexpr コンストラクタ を呼び出すこともできる(それらのオブジェクトが非リテラルクラス型の場合でも)。
(C++26まで)

変数 var は、以下の条件をすべて満たす場合に 定数初期化可能 である:

  • その初期化の 完全式 は、定数式を要求する文脈における定数式であり、すべての 契約表明 が「無視」評価セマンティクスを使用する。
  • var の初期化宣言の直後において、 var によって宣言されたオブジェクトまたは参照がconstexpr表現可能である。
  • var によって宣言されたオブジェクトまたは参照 x が静的またはスレッド記憶域期間を持つ場合、 x は、 var の初期化宣言に続く、直近の名前空間スコープである即時スコープの時点においてconstexpr表現可能である。

定数初期化可能な変数は、初期化子を持つか、その型が const-default-constructible である場合に 定数初期化 される。

(C++26以降)

定数式で使用可能

変数は、それが constexpr 変数 である場合、または参照型もしくは非volatileのconst修飾された整数型または列挙型である場合、 潜在的定数 となります。

定数初期化された潜在的に定数の変数 var は、点 P において 定数式で使用可能 である。ただし、 var の初期化宣言 D P から到達可能であり、以下のいずれかの条件が満たされる場合に限る:

  • var constexpr 変数です。
  • var TU-local 値で初期化されていません。
  • P D と同じ翻訳単位にあります。

オブジェクトまたは参照は、以下のいずれかのエンティティである場合、ポイント P において 定数式で使用可能 である:

  • ポイント P において定数式で使用可能な変数
  • 非volatile const修飾リテラル型の一時オブジェクトで、その寿命がポイント P において定数式で使用可能な変数の寿命まで延長されているもの
  • テンプレートパラメータオブジェクト
  • 文字列リテラル オブジェクト
  • 上記のいずれかの非変更可能な部分オブジェクト
  • 上記のいずれかの参照メンバ
(C++26まで)

オブジェクトまたは参照は、以下のいずれかのエンティティである場合、ポイント P において 定数式で使用可能である可能性がある

  • ポイント P において定数式で使用可能な変数
  • 非volatile const修飾リテラル型の一時オブジェクトで、その寿命がポイント P において定数式で使用可能な変数の寿命まで延長されているもの
  • テンプレートパラメータオブジェクト
  • 文字列リテラル オブジェクト
  • 上記のいずれかの非変更可能な部分オブジェクト
  • 上記のいずれかの参照メンバ

オブジェクトまたは参照は、ポイント P において定数式で使用可能である可能性があるオブジェクトまたは参照であり、かつポイント P においてconstexpr表現可能である場合、ポイント P において 定数式で使用可能 である。

(C++26以降)

明示的に定数評価される式

以下の式(変換先の型への変換を含む)は manifestly constant-evaluated です:

評価が明示的に定数評価されるコンテキストで行われるかどうかは、 std::is_constant_evaluated および if consteval (C++23以降) によって検出できます。

(C++20以降)

定数評価に必要な関数と変数

以下の式または変換は 潜在的に定数評価される 可能性があります:

関数は、constexpr関数であり、かつ定数評価される可能性のある式によって 名前が参照される 場合に、 定数評価のために必要 とされます。

変数は、それがconstexpr変数であるか、非volatileのconst修飾整数型または参照型であり、それを表す 識別子式 が定数評価される可能性がある場合、 定数評価に必要 とされます。

デフォルト化された関数の定義および 関数テンプレート 特殊化 または 変数テンプレート 特殊化 (C++14以降) のインスタンス化は、定数評価のためにその関数 または変数 (C++14以降) が必要とされる場合にトリガーされます。

定数部分式

定数部分式 とは、式 e 部分式 として評価された場合に、 e コア定数式 であることを妨げない式のことです。ただし、 e は以下のいずれかの式ではないものとします:

(C++20以降)

注記

機能テストマクロ 標準 機能
__cpp_constexpr_in_decltype 201711L (C++20)
(DR11)
定数評価に必要な場合の関数と変数定義の生成 定数評価に必要な関数と変数
__cpp_constexpr_dynamic_alloc 201907L (C++20) constexpr 関数内での動的ストレージ期間操作
__cpp_constexpr 202306L (C++26) constexpr キャスト( void * からの変換):constexpr型消去に向けて
202406L (C++26) constexpr 配置 new および new [ ]
__cpp_constexpr_exceptions 202411L (C++26) constexpr 例外: [1] [2]

不具合報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

日本語訳:
DR 適用対象 公開時の動作 正しい動作
CWG 94 C++98 算術定数式は変数と静的データメンバを
含むことができなかった
含むことができるようになった
CWG 366 C++98 文字列リテラルを含む式
は整数定数式になり得た
それらは該当しない
CWG 457 C++98 volatile変数を含む式
が整数定数式になり得た
それらは整数定数式ではない
CWG 1293 C++11 文字列リテラルが定数式で使用可能かどうかが不明確であった
使用可能である
CWG 1311 C++11 volatile glvalues could be used in constant expressions prohibited
CWG 1311 C++11 volatile glvaluesを定数式で使用可能であった 禁止
CWG 1312 C++11 reinterpret_cast は定数式では禁止されているが、
void * との間のキャストで同じ効果が達成可能
禁止された変換
cv void * から
オブジェクト型へのポインタ型
CWG 1313 C++11 未定義動作が許可されていた;
全てのポインタ減算が禁止されていた
UB禁止; 同一配列内の
ポインタ減算は許可
CWG 1405 C++11 定数式で使用可能なオブジェクトについて、
そのmutableな部分オブジェクトも使用可能であった
使用不可となった
CWG 1454 C++11 constexpr関数を介した参照経由での定数の受け渡しは許可されていなかった
参照経由での定数の受け渡し
許可
CWG 1455 C++11 変換済み定数式はprvalueのみ可能であった lvalueも可能
CWG 1456 C++11 アドレス定数式は配列の終端を1つ超えたアドレスを
指定できなかった
許可された
CWG 1535 C++11 a typeid 式のオペランドが多態クラス型の場合、
ランタイムチェックが含まれない場合でも
コア定数式ではなかった
オペランドの制約は
多態クラス型の
グローバル値に限定される
CWG 1581 C++11 定数評価に必要な関数は
定義またはインスタンス化が必須ではなかった
必須
CWG 1613 C++11 コア定数式はラムダ式内の任意の
odr-used参照を評価可能であった
一部の参照は
評価できなかった
CWG 1694 C++11 静的ストレージ期間を持つ参照への一時オブジェクトの値のバインドは定数式であった
これは定数式ではない
CWG 1872 C++11 コア定数式が constexpr 関数テンプレートのインスタンス化を呼び出せる可能性があった
そのインスタンス化は constexpr 関数の要件を満たさない
そのようなインスタンス化は
呼び出せない
CWG 1952 C++11 標準ライブラリの未定義動作
は診断が要求されていた
診断されるかどうかは
未規定
CWG 2022 C++98 定数式の判定がコピー省略が行われるかどうかに
依存する可能性がある
コピー省略は常に
行われると仮定する
CWG 2126 C++11 const修飾されたリテラル型の定数初期化された寿命延長された一時オブジェクトが
定数式で使用できなかった
使用可能
CWG 2129 C++11 整数リテラルは定数式ではなかった 定数式である
CWG 2167 C++11 評価内のローカルな非メンバー参照
が評価を非constexprにした
非メンバー
参照が許可される
CWG 2278 C++98 CWG issue 2022 の解決は実装不可能であった コピー省略は
決して実行されないと仮定する
CWG 2299 C++14 定数評価において <cstdarg>
のマクロを使用できるかどうかが不明確であった
va_arg は禁止、
va_start は未規定
CWG 2400 C++11 定数式で使用可能でないオブジェクトおよびその生存期間が呼び出しを含む
式の外側で開始されたオブジェクトに対するconstexpr仮想関数の呼び出し
定数式ではない
CWG 2490 C++20 定数評価における(擬似)デストラクタ呼び出しに
制限が欠如していた
制限が追加された
CWG 2552 C++23 コア定数式を評価する際、制御フローは非ブロック変数の宣言を
通過できなかった
通過できるようになった
CWG 2558 C++11 不定値は定数式になり得る 定数式ではない
CWG 2647 C++20 volatile修飾型の変数は潜在的に定数となりうる そうではない
CWG 2763 C++11 [[ noreturn ]] の違反は定数評価中に
検出される必要がなかった
必須
CWG 2851 C++11 変換された定数式では
浮動小数点変換が許可されていなかった
非縮小変換の浮動小数点変換を
許可する
CWG 2907 C++11 コア定数式は
std::nullptr_t グル値に対して
左辺値から右辺値への変換を適用できなかった
そのような変換を
適用可能
CWG 2909 C++20 初期化子を持たない変数は、そのデフォルト初期化が
何らかの初期化の実行をもたらす場合にのみ
定数初期化可能であった
その型がconst-default-initializableである
場合にのみ定数初期化可能
CWG 2924 C++11
C++23
[[noreturn]] (C++11) または [[assume]] (C++23) の制約に違反する式が
コア定数式であるかどうかは未規定であった
実装定義である
P2280R4 C++11 この評価の外側で生存期間が開始されたオブジェクトまたは参照を参照する
識別子式または * this を含む式の評価は定数式ではない
定数式である可能性がある

関連項目

constexpr 指定子 (C++11) 変数または関数の値がコンパイル時に計算可能であることを指定する
(C++11) (C++17で非推奨) (C++20で削除)
型がリテラル型かどうかをチェックする
(クラステンプレート)
Cドキュメント for 定数式