変数テンプレート
概要
C++11までのテンプレート機能は、クラス、関数に対して適用可能であった。C++14では変数にも適用できるように拡張された。
変数テンプレートは namespaceスコープ(global含む), クラススコープで定義可能である。クラススコープで定義した変数テンプレートは、staticメンバ変数とする。 以下に変数テンプレートの構文を示す。
template <テンプレートパラメータリスト> 型名 変数名 初期化式_opt
初期化式はオプショナルであるが、初期化式を指定しないとテンプレートのインスタンス化が行われても単なる変数でしかないため、 初期化式を指定するのが基本的な使い方となる。 変数であるため、constexpr指定も可能であり、通常のテンプレートと同様に、特殊化なども可能である。
例えば、π(パイ)を扱う際に、型毎の適切な有効桁数で扱いたいというケースで有用である。 円の面積を求める場合には、以下のようになる。
template <class T>
constexpr T pi = T(3.1415926535897932385L);
template <class T>
T circular_area(T r) {
return pi<T> * r * r;
}
C++11までは、同様なことを実現するためには、以下のような手段があった。
- テンプレートクラスに、piの値を保持するstaticメンバ変数を定義する
- piの値を返すテンプレート関数を定義する
しかし、上記のやり方では定数式を表現させる上で不便となる点があったため、C++14で変数テンプレート機能が追加された。 例えばstaticメンバ変数を定義する場合では、初期化式を記述しているにも関わらずクラス外で実体の定義が必要となる。
template <class T>
class Pi {
public:
static constexpr T value = T(3.1415926535897932385L);
};
template <class T>
constexpr T Pi<T>::value; //OK but redundancy declaration.
テンプレート関数を定義する際の問題は、原因となっていた仕様が修正されたため、ここでは取り上げない。 なお、修正された仕様というのは、constexpr指定されたメンバ関数は暗黙的にconst修飾されるという仕様である。