变量模板 (C++14 起)
来自 cppreference.cn
变量模板定义了一族变量或静态数据成员。
目录 |
[编辑] 语法
template < parameter-list > variable-declaration |
(1) | ||||||||
template < parameter-list > requires constraint variable-declaration |
(2) | (C++20 起) | |||||||
variable-declaration | - | 变量的声明。声明的变量名成为模板名。 |
parameter-list | - | 非空的逗号分隔模板参数列表,其中每个参数要么是非类型参数、类型参数、模板参数,要么是这些参数的参数包。 |
constraint | - | 约束表达式,它限制了此变量模板接受的模板参数 |
[编辑] 解释
从变量模板实例化出的变量称为实例化变量。从静态数据成员模板实例化出的静态数据成员称为实例化静态数据成员。
变量模板可以通过命名空间作用域的模板声明引入,其中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
除非变量模板被显式特化或显式实例化,否则当在需要变量定义存在的上下文中引用变量模板的特化时,或者当定义的存在影响程序语义时(即如果表达式需要变量进行常量求值时),它会被隐式实例化(定义可能不会被使用)。
如果表达式需要变量进行常量求值,则变量定义的存在被认为会影响程序语义,即使不需要表达式的常量求值或常量表达式求值不使用该定义。
[编辑] 注意
在 C++14 中引入变量模板之前,参数化变量通常作为类模板的静态数据成员或返回所需值的 constexpr 函数模板实现。
变量模板不能用作模板模板实参。
功能测试宏 | 值 | 标准 | 特性 |
---|---|---|---|
__cpp_variable_templates |
201304L |
(C++14) | 变量模板 |
[编辑] 缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 发布时的行为 | 正确的行为 |
---|---|---|---|
CWG 2255 | C++14 | 尚不清楚静态 数据成员模板的特化是否为静态数据成员 |
它是 |