命名空间
变体
操作

变量模板 (C++14 起)

来自 cppreference.cn
< cpp‎ | language
 
 
C++ 语言
通用主题
流程控制
条件执行语句
if
迭代语句(循环)
for
range-for (C++11)
跳转语句
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 (直至 C++17*)
noexcept 说明符 (C++11)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
存储期说明符
初始化
 
 
 
 

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

目录

[edit] 语法

template < parameter-list > variable-declaration (1)
template < parameter-list > requires constraint variable-declaration (2) (C++20 起)
variable-declaration - 变量的声明。被声明的变量名成为模板名。
parameter-list - 模板形参的非空逗号分隔列表,其中每个形参可以是非类型形参类型形参模板形参,或者上述各项的形参包
constraint - 约束表达式,它约束为此变量模板所接受的模板实参

[edit] 解释

从变量模板实例化的变量被称为实例化变量。从静态数据成员模板实例化的静态数据成员被称为实例化静态数据成员

变量模板可以由命名空间作用域处的模板声明引入,其中 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

除非变量模板被显式特化或显式实例化,否则当变量模板的特化在需要变量定义存在的语境中被引用,或者如果定义的存续影响程序的语义(即,如果变量被表达式需要用于常量求值)(定义可以不被使用),则会隐式实例化它。

如果变量被表达式需要用于常量求值,即使不需要表达式的常量求值,或者常量表达式求值不使用该定义,变量定义的存续也被认为会影响程序的语义。

[edit] 注解

在 C++14 中引入变量模板之前,参数化变量通常实现为类模板的静态数据成员,或实现为返回所需值的 constexpr 函数模板。

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

特性测试宏 Std 特性
__cpp_variable_templates 201304L (C++14) 变量模板

[edit] 缺陷报告

以下行为更改缺陷报告被追溯应用到先前发布的 C++ 标准。

DR 应用于 发布时的行为 正确行为
CWG 2255 C++14 静态特化的含义不明确
数据成员模板是否为静态数据成员