Variable template (since C++14)
Шаблон переменной определяет семейство переменных или статических членов данных.
Содержание |
Синтаксис
template
<
parameter-list
>
variable-declaration
|
(1) | ||||||||
template
<
parameter-list
>
requires
constraint
variable-declaration
|
(2) | (since 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++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| CWG 2255 | C++14 |
было неясно, является ли специализация статического
шаблона члена данных статическим членом данных |
является |