constexpr宣言された変数は暗黙的にconstになる

プログラミングC/C++

constexprはc++11で導入されたキーワードで、変数や関数が定数式(Constant Expressions)であることを宣言することができる。

constexpr変数はコンパイル時に値が定まるので、template parameterや配列宣言時のサイズ指定に使用できる。

constexpr size_t N = 10;
std::array<int, N> hoge;
int fuga[N];

一言でいうと、const は値や戻り値が書き換え不可であることを宣言するのに対し、 constexpr は値や戻り値がROM化可能であることを宣言する。

constexprが付与された変数は、暗黙的にconstも付与される。

// 以下の2つは等価
constexpr int N = 334;
constexpr const int N = 334;

しかし、ポインタ型に対しconstexprをつける時は注意が必要である。

int x = 0;
// 以下の2つは等価
constexpr int* p = &x;
constexpr int* const p = &x;

// 以下は上の2式とは等価でない
constexpr const int* p = &x;

constexprは対象の変数がROM化可能(すなわち書き換え不可)であることを宣言するので、constが付与されるのは * の後になる。言い換えると、上記の例の場合、p 自体を実行時に変えることはできないが、 *p を通じて x の値を書き換えることはできるのである。

int x = 0;
int main(void) {
    int y = 10;
    constexpr int* p = &x;

    // OK: pの指す先の値を変えることができる
    *p = 20;

    // NG: p自体を変えることはできない
    // p = &y;

    // 参照でも同じ。
    constexpr int& r = x;

    // OK: rの指す先の値を変えることができる
    r = 30;

    return 0;
}

まとめると、以下のようになる。

  • constexpr 宣言された変数は自動的に const 宣言されたことになる
  • ただし、ポインタや参照が絡む場合、指す先の値を書き換えることはできる

参考

プログラミングC/C++

Posted by komori