C++11以降のC++はModern C++と言われ、それ以前のC++(古典的C++)に対して多くの言語仕様が追加された。古典的C++しか知らないプログラマがModern C++の言語仕様を使い倒したコードを見ても、さっぱり分からないかもしれない。
古典的C++を主戦場とするプログラマに対して、盲目的にModern C++に移行すべきだと言うつもりはない。ただ、Modern C++は古典的C++の上位互換であり、古典的C++の枠組みで書かれたコードに対してModern C++の一部の仕様をつまみ食い的に利用するだけでも、おいしいことはある。
そこで、古典的C++の枠組みでコードを書くプログラマがつまみ食いする価値のあるModern C++の仕様について、いくつかの記事に分けて紹介していく。
constexpr
constexprは、C++11で導入された定数式の表現方法である。大雑把に言えば、型情報のある#defineみたいなものだと思えば良い。
型情報のある定数としては、古典的C++でもconst指定が利用できるが、constは実行時に値が決まる(初期化される)のに対して、constexprはコンパイル時に値が決まるので、実行時のオーバーヘッドが少ない。
#define A 3 // Aはコンパイル時に型チェックなしで「3」に置換される
const int A = 3; // Aは値を変更しない変数として実行時に初期化される
constexpr int A = 3; // Aはコンパイル時に「int型の3」として扱われる
constexprの仕様については、 https://cpprefjp.github.io/lang/cpp11/constexpr.html を参照。
古典的C++のコードで、#defineあるいはconstを用いて記述されていた定数で、型情報があってコンパイル時に値が決まっていた方が好ましいものは、constexprに容易に書き直せるだろう。
特に#defineで定義されていた定数は、型情報を設けることでコンパイル時に潜在不具合を発見するきっかけになるかもしれない。