変数テンプレート (C++14以降)
変数テンプレートは、変数のファミリーまたは静的データメンバーのファミリーを定義します。
目次 |
[編集] 構文
template < parameter-list > variable-declaration |
(1) | ||||||||
template < parameter-list > requires constraint variable-declaration |
(2) | (C++20以降) | |||||||
| variable-declaration (変数宣言) | - | 変数の宣言。宣言された変数名はテンプレート名になります。 |
| parameter-list | - | 非空のコンマ区切りのテンプレートパラメータのリストで、それぞれは非型パラメータ、型パラメータ、テンプレートパラメータ、またはそれらのいずれかのパラメータパックです。 |
| constraint (制約) | - | この変数テンプレートが受け入れるテンプレートパラメータを制限する制約式 |
[編集] 解説
変数テンプレートからインスタンス化された変数はインスタンス化された変数と呼ばれます。静的データメンバーテンプレートからインスタンス化された静的データメンバーはインスタンス化された静的データメンバーと呼ばれます。
変数テンプレートは、名前空間スコープでテンプレート宣言によって導入され、そこでvariable-declarationが変数を宣言します。
template<class T> constexpr T pi = T(3.1415926535897932385L); // variable template template<class T> T circular_area(T r) // function template { return pi<T> * r * r; // pi<T> is a variable template instantiation }
クラススコープで使用される場合、変数テンプレートは静的データメンバーテンプレートを宣言します。
using namespace std::literals; struct matrix_constants { template<class T> using pauli = hermitian_matrix<T, 2>; // alias template template<class T> // static data member template static constexpr pauli<T> sigmaX = {{0, 1}, {1, 0}}; template<class T> static constexpr pauli<T> sigmaY = {{0, -1i}, {1i, 0}}; template<class T> static constexpr pauli<T> sigmaZ = {{1, 0}, {0, -1}}; };
他の静的メンバーと同様に、静的データメンバーテンプレートの定義が必要になる場合があります。そのような定義はクラス定義の外部で提供されます。名前空間スコープでの静的データメンバーのテンプレート宣言は、非テンプレートのクラステンプレートのデータメンバーの定義である場合もあります。
struct limits { template<typename T> static const T min; // declaration of a static data member template }; template<typename T> const T limits::min = { }; // definition of a static data member template template<class T> class X { static T s; // declaration of a non-template static data member of a class template }; template<class T> T X<T>::s = 0; // definition of a non-template data member of a class template
変数テンプレートが明示的に特殊化または明示的にインスタンス化されていない限り、変数テンプレートの特殊化が、変数の定義が存在することを要求するコンテキストで参照される場合、または定義の存在がプログラムのセマンティクスに影響を与える場合、つまり、式が定数評価のために必要な場合(定義は使用されないかもしれない)、暗黙的にインスタンス化されます。
変数の定義の存在は、式が定数評価のために必要とされる場合、たとえ式の定数評価が要求されなかったり、定数式評価が定義を使用しなかったりしても、プログラムのセマンティクスに影響を与えると考えられます。
[編集] 注釈
C++14で変数テンプレートが導入されるまでは、パラメータ化された変数は通常、クラステンプレートの静的データメンバーとして、または目的の値を返すconstexpr関数テンプレートとして実装されていました。
変数テンプレートはテンプレートテンプレート引数として使用できません。
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_variable_templates |
201304L |
(C++14) | 変数テンプレート |
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 2255 | C++14 | 静的データメンバーテンプレートの特殊化が静的データメンバーであるかどうかが不明瞭であった。 データメンバーテンプレートの特殊化が静的データメンバーである |
そうである |