名前空間
変種
操作

変数テンプレート (C++14以降)

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 
 
 

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

目次

[編集] 構文

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 静的データメンバーテンプレートの特殊化が静的データメンバーであるかどうかが不明瞭であった。
データメンバーテンプレートの特殊化が静的データメンバーである
そうである
English 日本語 中文(简体) 中文(繁體)