变量模板 (自 C++14 起)
来自 cppreference.com
变量模板定义了一组变量或静态数据成员。
内容 |
[编辑] 语法
template < 参数列表 > 变量声明 |
(1) | ||||||||
template < 参数列表 > requires 约束 变量声明 |
(2) | (自 C++20) | |||||||
变量声明 | - | 一个 声明 变量。声明的变量名成为模板名。 |
参数列表 | - | 一个非空的逗号分隔的 模板参数 列表,每个参数可以是 非类型参数、类型参数、模板参数,或 参数包。 |
约束 | - | 一个 约束表达式,用于限制此变量模板接受的模板参数。 |
[编辑] 解释
从变量模板实例化的变量称为实例化变量。从静态数据成员模板实例化的静态数据成员称为实例化静态数据成员。
变量模板可以在命名空间作用域中通过模板声明引入,其中 变量声明 声明一个变量。
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 函数模板。
变量模板不能用作 模板模板参数。
特性测试宏 | 值 | Std | 特性 |
---|---|---|---|
__cpp_variable_templates |
201304L | (C++14) | 变量模板 |
[编辑] 缺陷报告
以下行为更改的缺陷报告已追溯应用于之前发布的 C++ 标准。
DR | 应用于 | 发布的行为 | 正确的行为 |
---|---|---|---|
CWG 2255 | C++14 | 不清楚静态数据成员模板的特化是否是静态数据成员 它是 |
它不是 |