Шаблоны функции
Шаблоны, которые также называют родовыми или параметризованными типами, позволяют конструировать семейства функций и классов. В отличие от механизма перегрузки, когда для каждого набора формальных параметров устанавливается своя функция, шаблон семейства функций определяется один раз, но при этом оно параметризуется. Параметризовать в шаблоне функции можно тип возвращаемого функцией значения и типы параметров, количество и порядок которых должны быть фиксированы. В определении шаблона употребляется служебное слово template. Для параметризации используется список формальных параметров шаблона, который заключается в угловые скобки <>. Каждый формальный параметр шаблона помечен служебным словом class, за которым следует имя параметра.
Шаблон семейства функций состоит из двух частей – заголовка шаблона и определения функции, в котором тип возвращаемого значения и типы параметров обозначаются именами параметров шаблона.
template <class Ttype> тип имя_функции(список аргументов)
{/*тело функции*/}
Здесь Ttype – фиктивный тип, или список типов, через запятую, который используется при объявлении аргументов, локальных переменных и возвращаемых значений функции. Компилятор заменит этот фиктивный тип на один из реальных и создаст соответственно несколько перегружаемых функций, которые являются ограниченными, поскольку выполняют одни и те же действия. Например:
#include <iostream.h>//пример 50
#include <string.h>
template <class X> int find(X object, X *list, int size) {
int i;
for(i=0; i<size; i++)
if(object == list[i]) return i;
return -1;
}
int main(){
int a[ ]={1, 2, 3, 4};
char *c="это проверка";
double d[ ]={1.1, 2.2, 3.3};
cout << find(3, a, 4) << endl;
cout << find('a', c, strlen(c))<< endl;
cout << find(0.0, d, 3);
return 0;
}
Компилятор автоматически создает три перегруженные функции find(), соответствующие типам передаваемых аргументов.
Приведем пример определения шаблона функций, вычисляющих абсолютные значения числовых величин разных типов:
template <class type> type abs (type x) { return x > 0 ? x: -x;}
В качестве еще одного примера рассмотрим шаблон семейства функций для обмена значений двух передаваемых им параметров.
template <class T> void swap (T* x, T* y){
T z = *x;
*x = *y;
*y = x; }
Здесь параметр T шаблона функций используется не только для спецификации формальных параметров, но и в теле определения функции, где он задает тип вспомогательной переменной z.
Если в программе присутствует приведенный ранее шаблон семейства функций swap() и появится последовательность операторов:
long k = 4, d = 8; swap (&k, &d);
то компилятор сформирует определение функции:
void swap (long* x, long* y){
long z = *x;
*x = *y;
*y = z; }
Затем будет выполнено обращение именно к этой функции, и значения переменных k и d поменяются местами.
Если в той же программе присутствуют операторы:
double a = 2.44, b = 66.3; swap (&a, &b);
то сформируется и выполнится функция
void swap (double* x, double* y){
double x = *x;
*x = *y;
*y = x;
}