Variable template (since C++14)
| 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 | ||||||||||||||||
|
||||||||||||||||
| 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 | ||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| General | |||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||
| Literals | |||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||
| Operators | |||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||
| Conversions | |||||||||||||||||||||||||||||||||||||||||||||||||||
| Template parameters | ||||
| Template arguments | ||||
| Class templates | ||||
| Function templates | ||||
| Class member templates | ||||
| Variable templates (C++14) | ||||
| Template argument deduction | ||||
| Class template argument deduction (C++17) | ||||
| Explicit (full) specialization | ||||
| Partial specialization | ||||
| Dependent names | ||||
| Packs (C++11) | ||||
| sizeof... (C++11) | ||||
| Fold expressions (C++17) | ||||
| Pack indexing (C++26) | ||||
| SFINAE | ||||
| Constraints and concepts (C++20) | ||||
| requires expression (C++20) |
变量模板定义了一组变量或静态数据成员。
目录 |
语法
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 |
静态数据成员模板的特化是否属于静态数据成员
的规定不明确 |
属于静态数据成员 |