Пространства имён
Варианты
Действия

Шаблон переменной (начиная с C++14)

Материал из cppreference.com
< cpp‎ | language
 
 
Язык С++
Общие темы
Управление потоком
Операторы условного выполнения
if
Операторы итерации (циклы)
Операторы перехода
Функции
Объявление функции
Выражение лямбда-функции
Спецификатор inline
Спецификации динамических исключений (до C++17*)
Спецификатор noexcept (C++11)
Исключения
Пространства имён
Типы
Спецификаторы
decltype (C++11)
auto (C++11)
alignas (C++11)
Спецификаторы длительности хранения
Инициализация
Выражения
Альтернативные представления
Литералы
Логические - Целочисленные - С плавающей запятой
Символьные - Строковые - nullptr (C++11)
Определяемые пользователем (C++11)
Утилиты
Атрибуты (C++11)
Types
Объявление typedef
Объявление псевдонима типа (C++11)
Casts
Неявные преобразования - Явные преобразования
static_cast - dynamic_cast
const_cast - reinterpret_cast
Выделение памяти
Классы
Свойства функции класса
explicit (C++11)
static
Специальные функции-элементы
Шаблоны
Разное
 
 

Шаблон переменной определяет семейство переменных или статических элементов данных.

Содержание

[править] Синтаксис

template < список-параметров > объявление-переменной
объявление-переменной объявление переменной. Имя объявленной переменной становится именем шаблона.
список-параметров непустой список параметров шаблона, разделённых запятыми, каждый из которых является либо параметром не типом, параметром типом, параметром шаблоном или пакетом параметров любого из них.

[править] Объяснение

Переменная, созданная из шаблона переменной, называется созданной переменной. Статический элемент данных, созданный из шаблона статического элемента данных, называется экземпляром статического элемента данных.

Шаблон переменной может быть представлен объявлением шаблона в области видимости пространстве имён, где объявление-переменной объявляет переменную.

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 было неясно, является ли специализация шаблона статического
элемента данных статическим элементом данных
является