printШаблоны

printШаблоны функций

С помощью шаблонов функций можно определить алгоритм, который может быть применен к данным различных типов. Компилятор генерирует код при первом вызове по заданному шаблону. Шаблонная функция определяется как обычная функция, но её определение должно быть в заголовочном файле и перед заголовком функции необходимо написать:
template <параметры шаблона>
Параметрами шаблона чаще всего являются типы обрабатываемых функцией данных (перед именем такого параметра нужно написать typename или class), но допустимо также передавать константы и объекты, как и обычной функции. Для параметров шаблона можно указать значения по умолчанию.
Пример шаблона функции:
template <typename T>
inline T maximum(T a, T b)
{
  return  a < b ? b : a;
}
Если параметры шаблона относятся только к типам параметров функции, то её можно вызывать обычным образом, компилятор определит аргументы шаблона самостоятельно. В остальных случаях их нужно указать явно после имени функции в <>:
int a,b,c;
double d,e;
c=maximum(a,b); // оба аргумента функции имеют тип int, значит аргумент шаблона - тип int
e=maximum<double>(d,a); // тип аргумента шаблона нельзя определить по типу аргументов функции,
                    // указываем явно тип double
Как и обычные функции, шаблоны функций можно перегружать. Из набора шаблонных функций вызывается функция с наиболее специализированными параметрами, точно соответствующая аргументам при вызове.

Если определены одновременно обычные и шаблонные функции с одинаковым именем и при вызове не указаны аргументы для шаблона в <>, то сначала компилятор выполняет поиск обычной функции с точным соответствием типов параметров, затем шаблона функции с точным соответствием типов параметров, а затем пытается добиться соответствия аргументов с параметрами обычной функции с помощью операций преобразования.

В С++20 появились сокращенные шаблоны функций, определяемые через auto-параметры в заголовке функции. Для каждого такого параметра добавится собственный (безымянный) параметр типа в параметры шаблона:
void inc(auto& x) { ++x; }
// эквивалентно
template<typename T> void inc(T& x) { ++x; }
auto plus(auto x, auto y) { return x+y; }
// эквивалентно
template<typename T1, typename T2> auto plus(T1 x, T2 y)->decltype(x+y) { return x+y; }
При использовании auto для параметра лямбда-выражения получается обобщенное лямбда-выражение (реализуемое как объект, у которого operator()(...) определяется как шаблон):
auto dbl=[](auto x){ return x+x; }
auto x=dbl(2.5); // 5.0
auto s=dbl("abc"s); // "abcabc"
loading