Namespaces
Variants

Variable template (since C++14)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

変数テンプレートは、変数または静的データメンバーのファミリーを定義します。

目次

構文

template < parameter-list > variable-declaration (1)
template < parameter-list > requires constraint variable-declaration (2) (since C++20)
variable-declaration - 変数の declaration 。宣言された変数名はテンプレート名となる。
parameter-list - 空でないカンマ区切りの template parameters のリスト。各パラメータは constant parameter type parameter template parameter 、またはこれらのいずれかの parameter pack である。
constraint - この変数テンプレートが受け入れるテンプレートパラメータを制限する constraint expression

説明

変数テンプレートからインスタンス化された変数は instantiated variable と呼ばれます。静的データメンバーテンプレートからインスタンス化された静的データメンバーは instantiated static data member と呼ばれます。

変数テンプレートは、名前空間スコープでのテンプレート宣言によって導入することができ、その場合 variable-declaration は変数を宣言します。

template<class T>
constexpr T pi = T(3.1415926535897932385L); // 変数テンプレート
template<class T>
T circular_area(T r) // 関数テンプレート
{
    return pi<T> * r * r; // pi<T>は変数テンプレートのインスタンス化
}

クラススコープで使用される場合、variable templateはstaticデータメンバーテンプレートを宣言します。

using namespace std::literals;
struct matrix_constants
{
    template<class T>
    using pauli = hermitian_matrix<T, 2>; // エイリアステンプレート
    template<class T> // 静的データメンバーテンプレート
    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}};
};

他の staticメンバー と同様に、staticデータメンバーテンプレートの定義が必要になる場合があります。そのような定義はクラス定義の外側で提供されます。名前空間スコープでのstaticデータメンバーのテンプレート宣言は、クラステンプレートの非テンプレート データメンバー の定義となる場合もあります:

struct limits
{
    template<typename T>
    static const T min; // 静的データメンバーテンプレートの宣言
};
template<typename T>
const T limits::min = { }; // 静的データメンバーテンプレートの定義
template<class T>
class X
{
    static T s; // クラステンプレートの非テンプレート静的データメンバーの宣言
};
template<class T>
T X<T>::s = 0; // クラステンプレートの非テンプレートデータメンバーの定義

変数テンプレートが 明示的に特殊化 されていないか、明示的にインスタンス化されていない限り、変数テンプレートの特殊化が 変数定義の存在を必要とする 文脈で参照される場合、または定義の存在がプログラムの意味論に影響を与える場合、すなわち変数が式による 定数評価のために必要とされる 場合(定義が使用されない可能性がある)に、変数テンプレートは暗黙的にインスタンス化されます。

変数の定義の存在は、その変数が式による定数評価に必要である場合、たとえ式の定数評価が要求されていない場合や、定数式評価がその定義を使用しない場合であっても、プログラムの意味論に影響を与えると見なされます。

注記

C++14で変数テンプレートが導入されるまで、パラメータ化された変数は通常、クラステンプレートの静的データメンバーとして、または目的の値を返すconstexpr関数テンプレートとして実装されていました。

変数テンプレートは テンプレートテンプレート引数 として使用できません。

機能テストマクロ 標準 機能
__cpp_variable_templates 201304L (C++14) Variable templates

不具合報告

以下の動作変更欠陥報告書は、以前に公開されたC++標準に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
CWG 2255 C++14 静的データメンバーテンプレートの特殊化が静的データメンバーであるかどうかが不明確であった 静的データメンバーである