C++では、コンパイル時(コンパイルの段階)およびリンク時(リンクの段階)の定数があります。
const変数は、初期化後に変更できないオブジェクトです。しかし、constは必ずしも値がコンパイル時に知られていることを保証するわけではなく、実行時にのみ計算される場合があります。constexprは、式または関数がコンパイル時に計算されることを保証します。例:
const int x = time(0); // constだが、constexprではない:値は実行時に計算される constexpr int y = 2 + 2; // constexpr:コンパイル時に知られている constexpr int square(int x) { return x * x; } int arr[square(3)]; // 配列のサイズはコンパイル時の式
配列のサイズやテンプレートパラメータなど、コンパイラにアクセスできる定数式にはconstexprを使用してください。
constexprとして宣言された関数は、非定数の引数で呼び出すことができますか?
回答: はい!引数がコンパイル時に知られていれば、結果はコンパイル時に計算されます。引数が実行時にのみ知られている場合、関数は通常のように計算されます。
constexpr int double_val(int x) { return x * 2; } int val = std::rand(); int result = double_val(val); // 実行時に呼び出される
物語
モジュールの1つは、コンパイル時定数であると期待して
const intで配列のサイズを定義しました。別のコンパイラで実行時に値が計算されたため、エラーが発生し、配列のサイズが標準に適合しませんでした。
物語
ハッシュ計算において、
const変数が使用されていたため、コンパイラは計算を最適化できず、結果として新しいリリースで性能が2倍以上低下しました。
物語
現代の標準に移行する際に、キーワードを混同し、関数を
constとして宣言し、constexprではなくしたため、コンパイル時のテンプレート式に結果を使用できませんでした。迅速な診断でエラーが示されましたが、レビューの際にマスターブランチにマージされました。