Изучая новый стандарт C++, натолкнулся на нововведение «шаблоны переменных»
Синтаксис у шаблона следующий:
template < typename T >
constexpr T value = T(1234);
О применении шаблона написано:
Данная возможность позволяет создавать и использовать constexpr
шаблоны переменных, для более удобного сочетания с шаблонными алгоритмами.
Не вполне понимаю, как такая переменная будет использоваться в шаблонном алгоритме. Не могли бы Вы привести несколько примеров использования этого механизма? Также не понимаю, почему нельзя такое шаблонное constexpr
выражение заменить нешаблонным, ведь значение мы указываем явно, соответственно, и тип можем написать (вывести) явно.
В стандарте есть пример:
template<class T>
constexpr T pi = T(3.1415926535897932385L);
template<class T>
T circular_area(T r) {
return pi<T> * r * r;
}
Здесь шаблон переменной позволяет получить константу нужного размера - float/double/etc.
Другое популярное применение - это замена is_some<T>::value
на is_some_v<T>
, например
template< class T, class U >
inline constexpr bool is_same_v = is_same<T, U>::value; // C++17
Тут можно заметить, что при объявлении шаблона переменной тип этой переменной совсем не обязан совпадать с параметром шаблона или вообще быть как-то связан с параметром(-ами) шаблона. Большинство тривиальных примеров шаблонов переменных обычно дают переменной тот же самый тип, что использовался в параметре шаблона, что может создать ложное впечатление, как будто это требуется. На самом деле шаблонная переменная может иметь любой тип.
Например, пользуясь примером с площадью окружности, вы можете принять решение использовать "базовое" определение константы PI
с конкретным типом double
template<class T> constexpr double PI = 3.141592653589793;
а затем, пользуясь явной специализацией, добавить специализированные определения для отдельных плавающих типов
template<> constexpr float PI<float> = 3.1415927;
template<> constexpr long double PI<long double> = 3.141592653589793238L;
После этого можно будет реализовать "единую" шаблонную функцию вычисления площади окружности
template<class T> T circle_area(T r)
{
return PI<T> * r * r;
}
которая будет, например, работать и с целочисленными типами
int area = circle_area(10);
Для целочисленных типов в качестве константы PI
будет браться вариант "по умолчанию" с типом double
, а для плавающих типов будут использоваться специализированные значения этой константы.
Вариант реализации этой функции из ответа @Abyx, как вы наверное заметили, тоже будет "работать" с целочисленными типами. Но в том варианте константа Пи для целочисленных типов получит целочисленное значение 3
, что не всегда желательно.
Также можно добавить, что возможность включения статических членов-данных в шаблоны классов существовала в языке С++ с самого начала стандартизованных времен, т.е. в С++98. Это позволяло реализовывать "шаблоны переменных" уже тогда, пользуясь фактически той же самой техникой, которая в С++98 применялась для "шаблонных typedef", т.е. через помещение типов или переменных в "обертку" шаблонного класса. В частности, вышеприведенный пример может быть реализован на классическом С++98 как
template <typename T> struct PI { static const double value; };
template <typename T> const double PI<T>::value = 3.141592653589793;
template <> struct PI<float> { static const float value; };
const float PI<float>::value = 3.1415927;
template <> struct PI<long double> { static const long double value; };
const long double PI<long double>::value = 3.141592653589793238L;
template<class T> T circle_area(T r)
{
return PI<T>::value * r * r;
}
Принимая это во внимание, можно сказать, что шаблонные переменные не являются каким-то фундаментально новым свойством С++14. Они (выражаясь нестрого) являются просто "синтаксическим сахаром", более компактным и элегантным вариантом синтаксиса для записи вышеприведенного С++98 варианта реализации. Ситуация аналогична введенной в С++11 возможность объявления шаблонных typedef (через using
), которая тоже может быть названа "синтаксическим сахаром" над хорошо известной С++98 техникой "шаблонного typedef".
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Всем приветДовольно много учил язык c++ и работать в консольке уже поднадоело и хочется начать реализовывать небольшие проекты (работать...
Собственно код, помогите довести до ума, входит в бесконечный циклЕсли у кого есть другой рабочий код, то киньте его ниже