Шаблоны функций
С помощью шаблонов функций можно определить алгоритм, который может быть применен к данным различных типов. Компилятор генерирует код при первом вызове по заданному шаблону. Шаблонная функция определяется как обычная функция, но её определение должно быть в заголовочном файле и перед заголовком функции необходимо написать:
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); //
e=maximum<double>(d,a); //
//
Как и обычные функции, шаблоны функций можно перегружать. Из набора шаблонных функций вызывается функция с наиболее специализированными параметрами, точно соответствующая аргументам при вызове.
Если определены одновременно обычные и шаблонные функции с одинаковым именем и при вызове не указаны аргументы для шаблона в
<>, то сначала компилятор выполняет поиск обычной функции с точным соответствием типов параметров, затем шаблона функции с точным соответствием типов параметров, а затем пытается добиться соответствия аргументов с параметрами обычной функции с помощью операций преобразования.
В С++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); //
auto s=dbl("abc"s); //