Увидев ключевое слово template и следующее за ним определение функции компилятор запоминает шаблон для будущего использования и генерации кода не происходит до тех пор, пока функция не будет реально вызвана в ходе выполнения программы. Компилятор в этом случае генерирует код функции для типа, указанного при ее вызове, подставляя его везде вместо идентификатора типа в шаблоне. Это называется реализацией шаблона функции. Каждый реализованный шаблон функции называется шаблонной функцией.
Определим шаблон семейства функций, вычисляющих абсолютное значение числовых величин разных типов:
template <class T> T abs(T n) {return n<0 ? -n : n;}
Если имеем вызов функции abs(-10.3), то аргумент -10.3 воспринимается как имеющий тип double, и компилятор формирует определение
double abs(double n) {return n <0 ? -n : n;}
и выполняться будет именно эта функция.
При вызове функций с аргументами других типов, компилятор сгенерирует другое определение функции abs():
#include <iostream.h>
//-------------------------------------------------------------template <class T> //шаблон семейства функций T abs(T n)
T abs(T n)
{
return (n < 0) ? -n : n;
}
//-------------------------------------------------------------int main()
{
int i1 = 5; //инииализация переменных разных типов и знаков
int i2 = -6;
long l1 = 70000L;
long l2 = -80000L;
double d1 = 9.95;
double d2 = -10.15;
//вызовы функций
cout << "\nabs(" << i1 << ")=" << abs(i1); //abs(int)
cout << "\nabs(" << i2 << ")=" << abs(i2); //abs(int)
cout << "\nabs(" << l1 << ")=" << abs(l1); //abs(long)
cout << "\nabs(" << l2 << ")=" << abs(l2); //abs(long)
cout << "\nabs(" << d1 << ")=" << abs(d1); //abs(double)
cout << "\nabs(" << d2 << ")=" << abs(d2); //abs(double)
cout << endl;
return 0;
}
Результаты работы программы:
abs(5)=5
abs(-6)=6
abs(70000)=70000
abs(-80000)=80000
abs(9.95)=9.95
abs(-10.15)=10.15
Определим шаблон семейства функций для обмена значений двух передаваемых им параметров:
template <class T> void swap(T* x, T* y) {T z=*x; *x=*y; *y=z;}
При определении переменных long k=4, d=8; и вызове swap(&k, &d);
будет сформировано определение
void swap(long* x, long* y) {long z=*x; *x=*y; *y=z;}
При определении переменных double a=2.44, b=66.3; и вызове swap(&a, &b);
будет сформировано определение
void swap(double* x, double* y) {double z=*x; *x=*y; *y=z;}
Определим шаблон семейства функций для поиска минимального из трех значений, причем функция возвращает элемент с минимальным значением:
#include <iostream.h>
template <class T> T min3(T x, T y, T z)
{T min =x;
if (y<min) min = y;
if (z<min) min = z;
return min;
}
int main()
{int a=2, b=5, c=-5;
cout << min3(a*c, b, c) << endl; //-10
cout << min3(0.03*a, 10.0, 5.0) << endl; //0.06
return 0;
}
Если все 3 аргумента будут одного типа, компилятор создаст нужную функцию, если нет – то сообщение об ошибке.
Свойства параметров шаблона:
1. имена параметров шаблона имеют в определяемой шаблоном функции все права имени типа, т.е. с их помощью могут специализироваться параметры формата, определяться тип возвращаемого функцией значения, типы любых объектов, локализованных в теле функции;
2. в списке параметров шаблона может быть несколько параметров, но каждый должен начинаться со служебного слова class:
template <class type1, class type2, …>;
3. имена параметров шаблона уникальны во всем определении шаблона;
4. недопустимо использование в заголовке шаблона параметров с одинаковыми именами:
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.