名前空間
変種
操作

定数式

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

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

コンパイル時に評価できるを定義します。

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

int n = 1;
std::array<int, n> a1;  // Error: “n” is not a constant expression
const int cn = 2;
std::array<int, cn> a2; // OK: “cn” is a constant expression

目次

[編集] 定義

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

C++98 定数式のカテゴリ

整数定数式 (C++98)

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

以下のすべての条件を満たす式は、整数定数式 (integral constant-expression) です

  • 以下のエンティティのみを含みます
  • 算術型のリテラル
  • 列挙子
  • 以下のすべての条件を満たす変数または静的データメンバ
  • const修飾されていること。
  • volatile修飾されていないこと。
  • 整数型または列挙型であること。
  • 定数式で初期化されていること。
  • 浮動小数点リテラルは、整数型または列挙型に明示的に変換されない限り、使用しません。
  • 非整数型および非列挙型への変換を適用しません。
  • sizeof のオペランド内を除き、以下のエンティティを使用しません
  • 関数
  • クラスオブジェクト
  • pointer
  • reference
  • 代入演算子
  • インクリメント演算子
  • デクリメント演算子
  • 関数呼び出し演算子
  • カンマ演算子

その他の定数式のカテゴリ

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

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

算術定数式は、整数定数式の要件を満たす式ですが、以下の例外があります

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

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

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

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

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

メンバポインタ定数式は、修飾識別子にアドレス演算子を適用し、任意で明示的なメンバポインタ変換を前置することで作成されるメンバポインタ型の式です。

(C++11まで)

以下の式は、総称して定数式と呼ばれます

  • 非ポインタリテラル型の純粋右辺値 (prvalue) コア定数式
  • 静的ストレージ期間を持つオブジェクトまたは関数を指定する左辺値 (lvalue) コア定数式
  • 以下のいずれかの値に評価されるポインタ型の純粋右辺値コア定数式
  • 静的ストレージ期間を持つオブジェクトのアドレス
  • 関数のアドレス
  • ヌルポインタ値
(C++11以降)
(C++14まで)

以下のエンティティは定数式として許容される結果です

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

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

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

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

(C++26以降)

式が定数式であるかどうかを判断する際、コピー省略は行われないと仮定されます。

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

[編集] リテラル型

以下の型は、総称してリテラル型と呼ばれます

  • cv修飾される可能性のある void
  • スカラ型
  • 参照型
  • リテラル型の配列
  • 以下のすべての条件を満たす、cv修飾される可能性のあるクラス型
(C++17以降)
  • 以下のいずれかの条件を満たす集成体共用体型
  • バリアントメンバを持たない。
  • 非volatileなリテラル型のバリアントメンバを少なくとも1つ持つ。
  • 非共用体集成体型であり、その各無名共用体メンバが以下のいずれかの条件を満たす
  • バリアントメンバを持たない。
  • 非volatileなリテラル型のバリアントメンバを少なくとも1つ持つ。
  • コピーコンストラクタまたはムーブコンストラクタではないconstexpr コンストラクタ (テンプレート) を少なくとも1つ持つ型

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

[編集] コア定数式

コア定数式は、その評価が以下のいずれの言語構成要素も評価しない任意の式です

言語構成要素 バージョン 提案文書
this ポインタ。ただし、式の一部として評価されている constexpr 関数内、または暗黙的または明示的なクラスメンバアクセス式に現れる場合を除く N2235
定数式で使用可能ではない静的またはスレッドストレージ期間を持つブロック変数の宣言を通過する制御フロー (C++23から) P2242R3
  1. constexpr 宣言されていない関数 (またはコンストラクタ) を呼び出す関数呼び出し式
    constexpr int n = std::numeric_limits<int>::max(); // OK: max() is constexpr
    constexpr int m = std::time(nullptr); // Error: std::time() is not constexpr
  2. 宣言されているが定義されていないconstexpr関数への関数呼び出し
  3. constexpr関数/コンストラクタの要件を満たさないconstexpr関数/コンストラクタテンプレートのインスタンス化への関数呼び出し
  4. 動的型がconstexpr-unknownであるオブジェクトに対して呼び出される、constexpr仮想関数への関数呼び出し
  5. 実装定義の制限を超える式
  6. 評価が何らかの形のコア言語の未定義または誤った(C++26から)動作につながる式。ただし、標準属性によって導入される可能性のある未定義動作を除く。
    constexpr double d1 = 2.0 / 1.0; // OK
    constexpr double d2 = 2.0 / 0.0; // Error: not defined
    constexpr int n = std::numeric_limits<int>::max() + 1; // Error: overflow
    int x, y, z[30];
    constexpr auto e1 = &y - &x;        // Error: undefined
    constexpr auto e2 = &z[20] - &z[3]; // OK
    constexpr std::bitset<2> a; 
    constexpr bool b = a[2]; // UB, but unspecified if detected
  7. (C++17まで) ラムダ式
  8. 左辺値から右辺値への暗黙の変換。ただし、以下に適用される場合を除く...
    1. 型(cv修飾される可能性のある) std::nullptr_t のglvalue
    2. 定数式で使用可能なオブジェクトを指す、非volatileなリテラル型のglvalue
      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. 共用体の非アクティブメンバまたはそのサブオブジェクトに適用される左辺値から右辺値への暗黙の変換または変更 (アクティブメンバと共通の初期シーケンスを共有している場合でも)
  10. 値が不定であるオブジェクトに対する左辺値から右辺値への暗黙の変換
  11. この式の評価外で生存期間が開始した、アクティブメンバが可変 (mutable) である (もしあれば) 共用体の暗黙のコピー/ムーブコンストラクタ/代入の呼び出し
  12. (C++20まで) 共用体のアクティブメンバを変更する代入式
  13. voidへのポインタからオブジェクトポインタ型 T* への変換。ただし、ポインタがヌルポインタ値を保持するか、型が T類似しているオブジェクトを指す場合を除く(C++26から)
  14. dynamic_cast。そのオペランドが動的型がconstexpr-unknownであるオブジェクトを参照するglvalueである場合(C++20から)
  15. reinterpret_cast
  16. (C++20まで) 疑似デストラクタ呼び出し
  17. (C++14まで) インクリメントまたはデクリメント演算子
  18. (C++14から) オブジェクトの変更。ただし、オブジェクトが非volatileなリテラル型であり、その生存期間が式の評価内で開始した場合を除く
    constexpr int incr(int& n)
    {
        return ++n;
    }
     
    constexpr int g(int k)
    {
        constexpr int x = incr(k); // Error: incr(k) is not a core constant
                                   // expression because lifetime of k
                                   // began outside the expression incr(k)
        return x;
    }
     
    constexpr int h(int k)
    {
        int x = incr(k); // OK: x is not required to be initialized
                         // with a core constant expression
        return x;
    }
     
    constexpr int y = h(1); // OK: initializes y with the value 2
                            // h(1) is a core constant expression because
                            // the lifetime of k begins inside the expression h(1)
  19. (C++20から) この式の評価内で生存期間が開始しなかったオブジェクトのデストラクタ呼び出しまたは疑似デストラクタ呼び出し
  20. 多相型のglvalueに適用されるtypeidであり、そのglvalueが動的型がconstexpr-unknownであるオブジェクトを参照する場合(C++20から)
  21. new。ただし、以下の条件のいずれかが満たされる場合を除く:(C++20から)
    • 選択された割り当て関数が置換可能なグローバル割り当て関数であり、割り当てられたストレージがこの式の評価内で解放される。
    (C++20以降)
    • 選択された割り当て関数が、割り当てられた型 T を持つ非割り当て形式であり、配置引数が以下のすべての条件を満たす
    • 以下を指す
    • T が配列型でない場合、型が T に類似するオブジェクト、または
    • T が配列型である場合、型が T に類似するオブジェクトの最初の要素。
    • この式の評価内で期間が開始したストレージを指す。
    (C++26以降)
  22. delete。ただし、この式の評価内で割り当てられたストレージ領域を解放する場合を除く(C++20から)
  23. (C++20から) コルーチン: await-expression または yield-expression
  24. (C++20から) 結果が未指定の場合の三方比較
  25. 結果が未指定の等価演算子または関係演算子
  26. (C++14まで) 代入演算子または複合代入演算子
  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)); // OK since C++26
    static_assert(always_throw()); // Error: uncaught exception
  29. asm-declaration
  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: outside of a lambda-expression
     
        [=]
        {
            constexpr int i = n;   // OK: 'n' is not odr-used and not captured here.
            constexpr int j = *&n; // Ill-formed: '&n' would be an odr-use of 'n'.
        };
    }

    注意: ODR-useがクロージャへの関数呼び出しで行われる場合、それは this や囲む変数を参照しません。代わりにクロージャのデータメンバにアクセスするためです。

    // OK: 'v' & 'm' are odr-used but do not occur in a constant-expression
    // within the nested lambda
    auto monad = [](auto v){ return [=]{ return v; }; };
    auto bind = [](auto m){ return [=](auto fvm){ return fvm(m()); }; };
     
    // OK to have captures to automatic objects created during constant expression evaluation.
    static_assert(bind(monad(2))(monad)() == monad(2)());
    (C++17以降)

[編集] 追加要件

E が上記のいずれも評価しない場合でも、E を評価することが実行時未定義の動作になる場合、E がコア定数式であるかどうかは実装定義です。

E が上記のいずれも評価しない場合でも、E を評価することが以下のいずれかを評価する場合、E がコア定数式であるかどうかは未規定です

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

式がコア定数式であるかどうかを判断する目的で、共用体のトリビアルなコピー/ムーブコンストラクタまたはコピー/ムーブ代入演算子の呼び出しの評価は、共用体のアクティブなメンバ (もしあれば) をコピー/ムーブすると見なされます。

式がコア定数式であるかどうかを判断する目的で、構造化束縛 bd を名指す識別子式の評価は、以下のセマンティクスを持ちます

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

式をコア定数式として評価する間、式の評価外で生存期間が開始したオブジェクトまたは参照を参照するすべての識別子式および *this の使用は、そのオブジェクトまたは参照の特定のインスタンスを参照するものとして扱われ、その生存期間およびすべてのサブオブジェクト (すべての共用体メンバを含む) の生存期間は、定数評価全体を含みます。

  • そのようなオブジェクトで定数式で使用可能ではない(C++20から)ものについては、オブジェクトの動的型はconstexpr-unknownです。
  • そのような参照で定数式で使用可能ではない(C++20から)ものについては、参照は、参照される型の未指定のオブジェクトに束縛されているものとして扱われ、その生存期間およびすべてのサブオブジェクトの生存期間は定数評価全体を含み、その動的型はconstexpr-unknownです。

[編集] 整数定数式

整数定数式は、整数型または非スコープ列挙型の式で、暗黙的に純粋右辺値に変換され、変換された式がコア定数式であるものです。

整数定数式が期待される場所でクラス型の式が使用される場合、その式は整数型または非スコープ列挙型に文脈的に暗黙変換されます。

[編集] 変換定数式

T変換定数式は、型 T暗黙変換される式であり、変換された式は定数式であり、暗黙の変換シーケンスは以下のみを含みます

(C++17以降)

そして、参照束縛が行われる場合、それは直接束縛のみです。

以下の文脈では変換定数式が必要です

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

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

以下の文脈では型 bool の文脈的変換定数式が必要です

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


構成エンティティ

オブジェクト obj構成値は次のように定義されます

オブジェクト obj構成参照には、以下の参照が含まれます

  • 参照型を持つ obj の直接メンバ
  • 非アクティブな共用体メンバを除く obj の直接サブオブジェクトの構成参照

変数 var構成値構成参照は次のように定義されます

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

変数 var の任意の構成参照 ref について、ref が一時オブジェクトまたはそのサブオブジェクトに束縛され、その寿命が ref の寿命に延長される場合、その一時オブジェクトの構成値と参照も再帰的に var の構成値と参照になります。

Constexprで表現可能なエンティティ

静的ストレージ期間を持つオブジェクトは、プログラムのどの時点でもconstexpr参照可能です。

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

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

  • x の各構成値がオブジェクト obj を指す場合、objP からconstexpr参照可能です。
  • x の各構成値がオブジェクト obj の次を指す場合、objP からconstexpr参照可能です。
  • x の各構成参照がオブジェクト obj を参照する場合、objP から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 の初期化宣言 DP から到達可能であり、かつ以下のいずれかの条件が満たされる場合です

  • varconstexpr 変数です。
  • var翻訳単位ローカルな値に初期化されていません。
  • PD と同じ翻訳単位内にあります。

オブジェクトまたは参照は、点 P定数式で使用可能です。それが以下のエンティティのいずれかである場合です

(C++26まで)

オブジェクトまたは参照は、点 P潜在的に定数式で使用可能です。それが以下のエンティティのいずれかである場合です

オブジェクトまたは参照は、点 P定数式で使用可能です。それが P で潜在的に定数式で使用可能であり、かつ P でconstexpr表現可能である場合です。

(C++26以降)

明白な定数評価式

以下の式 (宛先型への変換を含む) は明白な定数評価です

評価が明白な定数評価コンテキストで行われるかどうかは、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) void* からの constexpr キャスト: constexpr 型消去に向けて
202406L (C++26) constexpr 配置 newnew[]
__cpp_constexpr_exceptions 202411L (C++26) constexpr 例外

[編集]

[編集] 欠陥報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
CWG 94 C++98 算術定数式は
変数や静的データメンバを含むことができなかった
できるようになった
CWG 366 C++98 文字列リテラルを含む式
は整数定数式になる可能性があった
ならない
CWG 457 C++98 volatile変数を含む式
は整数定数式になる可能性があった
ならない
CWG 1293 C++11 文字列リテラルが
定数式で使用可能かどうかが不明確だった
使用可能である
CWG 1311 C++11 volatile glvalueは定数式で使用できた 禁止された
CWG 1312 C++11 reinterpret_castは定数式では禁止されているが、
void*との間のキャストで同じ効果が得られた
禁止された変換
cv void* から
オブジェクトポインタ型へ
CWG 1313 C++11 未定義動作は許可されていた;
すべてのポインタ減算は禁止されていた
UB禁止;同一配列内
ポインタ減算はOK
CWG 1405 C++11 定数式で使用可能なオブジェクトについて、
その可変サブオブジェクトも使用可能だった
使用可能ではない
CWG 1454 C++11 constexpr関数を通じて参照で定数を渡すこと
は許可されていなかった
許可
CWG 1455 C++11 変換定数式はprvalueのみであった lvalueも可能
CWG 1456 C++11 アドレス定数式は
配列の終端の次のアドレスを指すことができなかった
許可
CWG 1535 C++11 オペランドが多相クラス型の
typeid 式は、実行時チェックが関与しなくても
コア定数式ではなかった
オペランドの制約
は、多相クラス型の
glvalueに限定される
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 glvalueに
左辺値から右辺値への変換を適用できなかった
そのような
変換を適用できる
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言語のドキュメント
English 日本語 中文(简体) 中文(繁體)