15

このconstexprキーワードは C++11 で導入されました。これは、(私が思うに) 「定数式」の対応する考え方だったからです。ただし、配列宣言には定数式が必要なため、この概念は C++98/c++03 に暗黙的に存在していました。

// valid:
int a[sizeof(int)];
int b[3+7];
int c[13/4];
const int n = 3;
int d[n];
// invalid:
int m = 4;
int e[m];

他の「定数式」、つまり、コンパイル時に評価できる (および/または評価する必要がある) 式があります。その一例がテンプレート引数です。

C++11 より前の場合、C++98/03 標準または他の場所に次のものが存在しますか?

  • 定数式を必要とする構文構造の完全なリスト (配列宣言やテンプレートのインスタンス化など)
  • そのような定数式を管理する規則 (おそらくこれは、上記のリストの項目から標準の定義へのマッピングにすぎません)
4

1 に答える 1

13

constexpr定数式は、定数式を使用できる場所で変数または関数を使用できることをconstexprが示すという点で関連しています。これは、cppreference が教えてくれることです:

constexpr 指定子は、コンパイル時に関数または変数の値を評価できることを宣言します。そのような変数と関数は、コンパイル時の定数式のみが許可されている場所で使用できます。

定数式は C++11 より前に存在し、C++11 より前の定数式を管理する規則は、C++03 ドラフト標準の同じ場所でカバーされています(これは C++03 に最も近い公開ドラフトです) 1 C++11 標準の草案である5.19 定数式のセクションである cppreference には、定数式のページでこのトピックに関する優れた要約がありますが、C++11 および C++14 を対象としており、C++ より前に何が適用されるかを判断するのは困難です。 +11。

C++11 より前の標準では、最初の段落に定数式が必要な場所がリストされており、5.19完全に見えます。

いくつかの場所で、C++ は整数または列挙定数に評価される式を必要とします: 配列境界 (8.3.4、5.3.4)、ケース式 (6.4.2)、ビットフィールド長 (9.6)、列挙子初期化子として(7.2)、静的メンバー初期化子 (9.4.2)、および整数型または列挙型の非型テンプレート引数 (14.3) として。

段落1の残りの部分は次のように述べています。

整数の定数式には、算術型のリテラル (2.13、3.9.1)、列挙子、不揮発性 const 変数、または定数式で初期化された整数型または列挙型の静的データ メンバー (8.5)、型のないテンプレート パラメーターのみを含めることができます。整数型または列挙型、および sizeof 式。浮動リテラル (2.13.3) は、整数型または列挙型にキャストされている場合にのみ表示できます。整数型または列挙型への型変換のみを使用できます。特に、sizeof 式を除いて、関数、クラス オブジェクト、ポインター、または参照は使用してはならず、代入、インクリメント、デクリメント、関数呼び出し、またはコンマ演算子は使用してはなりません。

5その後に、さらなる要件をリストするパラグラフが続きます。

C++11 では、パラグラフ3に定数式を使用できる場所のリストがありますが、それらが必要な場所は明確ではありません。おそらく、定数式という用語を検索して、それが必要なすべての場所を見つける必要があります。通常、次のようなフレーズがあります。

は定数式でなければなりません

しなければならないという要件に違反すると、プログラムが不適切な形式になるため、しなければならないということは重要な用語です。

Annex A または、 Grammar summaryを使用して定数式を検索することもできます。これは、定数式が必要な文法内のすべての場所をカバーする必要があります。次に例を示します。

enumerator = constant-expression

脚注:

  1. この回答は、現在の C または C++ 標準ドキュメントはどこにありますか? ドラフト規格の完全なリストがあります。残念ながら、一般に公開されている最も近いのは早い段階から2005です。以前のバージョンでは認証が必要です。私の知る限り、セクション5.19はあまり変わりませんでした。
于 2014-09-24T19:34:10.923 に答える