【C++】constとconstexprの違い

個人メモ.

C++の定数

  • C++の定数は2種類ある

constexprの概要

  • constexprは
    • C++で導入された指定子
    • 変数の定義,関数や関数テンプレートの宣言,リテラル型の静的データメンバの宣言に適用する

constexpr int zero = 0;   // constexpr 変数
auto x = foo<int, zero>;    // テンプレートに渡すことが可能
  • constexpr宣言された関数やコンストラクタは,コンパイル時と実行時に呼び出せる
constexpr int zero(){return 0;}     // constexpr関数
constexpr int cc_time_zero = zero();  // コンパイル時に呼び出し
int runtime_zero = zero();     // 実行時に呼び出し
struct literal_type{};
constexpr auto literal = literal{};
  • constexprとは
    • C++11から導入された修飾子
    • 定数式を記述するための指定子

constとの違い

  • const
    • 定数としてオブジェクトを宣言する.
      これはオブジェクトが変更されず値が変わらないことを意味する.
      コンパイラは最適化に利用する. 初期化されたあとに,プログラマが誤って上書きしてはいけないオブジェクトを変更するのを防止できる.
    • コンパイル時に定数でなくてもよい.
    • 初期化子が定数式の場合,定数式になる. それ以外の場合はconst修飾しているだけ.

  • 固定長配列のサイズはコンパイル時定数のみを指定できる.
  • したがって,以下はエラーになる.
    (Xは定数だが,xは実行時定数)
struct X { int n; };
const X x = {123};
int a[x.n] = { 1 };
  • これを解決するには,Xにconstexpr指定し,明示的にコンパイル時定数として扱う.
struct X { int n; };
constexpr X x = {123};
int a[x.n] = { 1 };