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

Шаблоны, которые также называют родовыми или параметризованными типами, позволяют конструировать семейства функций и классов. В отличие от механизма перегрузки, когда для каждого набора формальных параметров устанавливается своя функция, шаблон семейства функций определяется один раз, но при этом оно параметризуется. Параметризовать в шаблоне функции можно тип возвращаемого функцией значения и типы параметров, количество и порядок которых должны быть фиксированы. В определении шаблона употребляется служебное слово 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;

}