变量模板(C++14 起)

< cpp‎ | language

变量模板定义一族变量或静态数据成员。

语法

template < 形参列表 > 变量声明

解释

变量声明 - 变量的声明。声明的变量名成为模板名。
形参列表 - 非空的模板形参的逗号分隔列表,每项是非类型形参类型形参模板形参,或任何上述的形参包之一。

变量模板可以由处于命名空间作用域中的模板声明引入,其中 声明 声明一个变量。

template<class T>
constexpr T pi = T(3.1415926535897932385L);  // 变量模板
 
template<class T>
T circular_area(T r) // 函数模板
{
    return pi<T> * r * r; // pi<T> 是变量模板实例化
}

在类作用域中使用时,变量模板声明一个静态数据成员模板。

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 } };
};

与其他静态成员一样,静态数据成模板的需要一个定义。这种定义可以在类定义外提供。处在命名空间作用域的静态数据成员的模板声明亦可为类模板的非模板数据成员的定义:

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 函数模板。

变量模板不能用作模板模板实参