Перегруженные функции обычно используют для выполнения сходных операций над различными
типами данных.
Если для каждого типа данных должны выполняться идентичные (абсолютно одинаковые) операции,
то более компактным и удобным решением является использование шаблонов функций.
Шаблоны функций экономят много времени, так как шаблон мы пишем только один раз, а
использовать можем с разными типами данных.
Шаблон функции – обобщенное описание функции, алгоритм которой реализуется независимо от
типа данных.
//В конспект не писать.
Если посмотреть определение слова «шаблон» в словаре, то увидим следующее: «Шаблон —
это образец, по которому изготавливаются похожие изделия». Например, шаблоном
является трафарет — объект (например, пластинка), в котором прорезан
рисунок/узор/символ. Если приложить трафарет к другому объекту и распылить краску, то
получим этот же рисунок, прилагая минимум усилий, быстро и, что не менее важно, мы
сможем сделать десятки этих рисунков разных цветов! При этом нам нужен лишь один
трафарет и нам не нужно определять цвет рисунка заранее (до использования трафарета).
В C++ шаблоны функций — это функции, которые служат образцом для создания других
подобных функций. Главная идея — создание функций без указания точного типа некоторых
или всех переменных. Вместо этого мы определяем функцию, указывая тип параметра
шаблона, который используется вместо любого типа данных. После того, как мы создали
функцию с типом параметра шаблона, мы фактически создали «трафарет функции».
При вызове шаблона функции, компилятор использует «трафарет» в качестве образца
функции, заменяя тип параметра шаблона на фактический тип переменных, передаваемых в
функцию!
Другими словами, шаблоны определяют функцию на основе обобщенного типа данных, вместо
которого может быть подставлен конкретный тип данных. Передавая функции конкретный тип
данных в виде параметра на этапе компиляции, компилятор автоматически генерирует функцию для
этого типа данных. Таким образом, создается функция, которая автоматически перегружает сама
себя.
Поскольку шаблоны позволяют программировать на основе обобщенного типа вместо
определенного типа данных, этот тип программирования называют обобщенным
программированием.
Определение шаблона
Шаблон функции создается с помощью ключевого слова template, которое сообщает
компилятору, что дальше будет объявлены параметры шаблона.
Для создания формальных типов параметров шаблона используется ключевое слово typename,
после которого указывается имя типа (в нашем примере имя типа Type). Формальные типы
параметров используются для задания: типов параметров, типов возвращаемого значения,
типов локальных переменных внутри тела функции. Далее идет обычное описание функции.
templeate < typename Type>
Тип возвращаемого значения Имя функции (список параметров)
{ операторы функции;}
Шаблон не создает никаких функций.
Шаблон предоставляет компилятору указания, как необходимо создать версию функции
шаблона для конкретного типа данных.
Когда компилятор создает версию функции шаблона для конкретного типа данных, говорят, что
он создал порожденную функцию.
Порожденная функция – конкретный экземпляр функции-шаблона
//C++ не компилирует шаблоны функций напрямую. Вместо этого, когда компилятор встречает
вызов шаблона функции, он копирует шаблон функции и заменяет типы параметров шаблона
функции фактическими (передаваемыми) типами данных. Функция с фактическими типами
данных называется экземпляром шаблона функции.
Экземпляр функции-шаблона – это функции с фактическими типами данных
Экземпляр функции-шаблона вызывается как обычная.
Пример. Создать шаблон для функции, которая суммирует значения двух переменных. Алгоритм
такой функции одинаков для всех численных данных (например short, int, long, float, double, long
double).
В заголовке шаблона этой функции объявлен единственный формальный параметр Type как тип
данных, которые должны обрабатываться функцией Sum (). В заголовке функции параметр Type
используется для задания типа возвращаемого значения функции, для задания типа параметров.
///////////шаблон функци
templeate < typename Type>
Type Sum( Type x1, Type y1)
{ return x1 + y1;}
////////////////////////////////////////////////////////////////////////////////////////////
void main(){
int x=100, y=200;
int s=Sum(x,y); //вызов функции int Sum ( int , int)
cout<<”Сумма двух целочисленных значений типа ”<<s;
float fx=100, fy=200;
float fs=Sum( fx, fy); //вызов функции float Sum (float, float)
cout<<”Сумма двух целочисленных значений типа ”<<fs;
double dx=100, dy=200;
double ds=Sum( dx, dy); //вызов функции double Sum (double, double)
cout<<”Сумма двух целочисленных значений типа ”<<ds;}
Все вызова функции Sum() имеют параметры разных типов. Поскольку мы вызываем функцию
Sum() с тремя разными типами параметров, то компилятор использует шаблон функции для
создания трёх разных версий функции Sum():
Версия функции шаблона для типа int имеет вид - int Sum ( int, int)
Версия функции шаблона для типа float имеет вид - float Sum ( float, float)
Версия функции шаблона для типа double имеет вид - double Sum (double, double)
Пример. Написать шаблон функции, возвращающей минимальный элемент массива, применить эту
функцию для обработки массивов различных стандартных типов данных.
В заголовке шаблона этой функции объявлен единственный формальный параметр Type как тип
данных, которые должны обрабатываться функцией Min_mas(). В заголовке функции параметр Type
используется для задания типа возвращаемого значения функции, для задания типа массива Type *,
внутри функции параметр Type применен для определения типа локальной переменной min
///////шаблон функции
template <typename Type>
Type Min_mas (Тype * mas1, int n1)
{Тype min = mas1 [0];
for (int i = 1; i <n1; i ++)
if (mas1 [ij <min) min = mas1 [i];
return min;
}
//////////////////////////////////////////
void main ()
{const int n1=5;
int mas_int [n1] = {1, 6, 8, 5, 9}; // целочисленный массив
int min_int=Min_mas (mas_int, n1); //вызов функции int Min_mas() ( int *, int)
cout << "min массива целочисленных элементов =" << min_int <<endl;
Все вызова функции Min_mas() имеют параметры разных типов. Поскольку мы вызываем
функцию Min_mas() с двумя разными типами параметров, то компилятор использует шаблон
функции для создания двух разных версий функции Min_mas():
Версия функции шаблона для типа int имеет вид - int Min_mas() ( int *, int)
Версия функции шаблона для типа float имеет вид - float Min_mas() ( float *, int)
В шаблоне функции может быть объявлено несколько формальных типов данных. При этом каждый
из объявленных типов должен хотя бы один раз появиться в списке параметров функции.
Пример. Написать шаблон функции, который выводит на экран значения параметров через пробел.
В заголовке шаблона этой функции объявлены два формальных параметра Type1 и Type2, как типы
данных, которые должны обрабатываться функцией Vuvod_2type ().
///////шаблон функции
template <typename Type1, typename Type2>
void Vuvod_2type (Тype1 x, Type2 y)
{ cout<< x << ‘ ‘<< y << ednl;}
//////////////////////////////////////////
void main ()
{int x=100; char str[80]=”Privet”;
Vuvod_2type ( x, str); //вызов функции void Vuvod_2type ( int , char*)
Vuvod_2type ( 5, 5.0); //вызов функции void Vuvod_2type ( int , double)
Vuvod_2type ( ‘A’, str); //вызов функции void Vuvod_2type ( char , char*)
}
Все вызова функции Vuvod_2type имеют параметры разных типов. Поскольку мы вызываем
функцию Vuvod_2type с тремя разными типами параметров, то компилятор использует шаблон
функции для создания трех разных версий функции Vuvod_2type().
Версия функции шаблона для типа int и типа char* имеет вид - void Vuvod_2type ( int , char*)
Версия функции шаблона для типа int и типа double имеет вид - void Vuvod_2type ( int , double)
Версия функции шаблона для типа chat и типа char* имеет вид - void Vuvod_2type ( char , char*)