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 < 形参列表 > 变量声明 (1)
template < 形参列表 > requires 约束条件 变量声明 (2) (C++20 起)
variable-declaration - 变量的 声明 。被声明的变量名成为模板名称。
parameter-list - 非空的逗号分隔 模板形参 列表,其中每个形参可以是 常量形参 类型形参 模板形参 ,或这些形参的任意 形参包
constraint - 限制此变量模板所接受模板形参的 约束表达式

说明

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

变量模板可以通过命名空间作用域的模板声明引入,其中 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> 是变量模板实例化
}

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

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

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

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

缺陷报告

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

缺陷报告 应用于 发布时的行为 正确行为
CWG 2255 C++14 静态数据成员模板的特化是否属于静态数据成员
的规定不明确
属于静态数据成员