11.1 Функции-шаблоны (родовые функции)

Если функции выполняют одинаковые действия, но над данными разных типов, то можно определить одну функцию-шаблон.

Определение имеет формат

template <class X[, class Y,…]> определение _функции.

Причем вместо типа какого-либо аргумента (или всех) или возвращаемого значения может стоять X, Y,…, где X, Y, … –  идентификаторы для обозначения произвольного типа данных.

Рассмотрим такую задачу: отсортировать массив целых чисел и строк методом пузырька.

Вообще говоря, потребовалось бы создать 2 функции для сортировки каждого массива и 2 для обмена двух значений, т.е. 4 функции. Вместо этого  напишем 2 функции-шаблона. Определим дополнительно еще 2 функции-шаблона – для нахождения max элемента в массиве данных и вывода на экран двух значений данных разного типа.

#include <iostream.h>

#include <stdlib.h>

#include <conio.h>

#include <string.h>

#include <math.h>

enum boolean{FALSE,TRUE};

#include "string.hpp"

#include "complex.hpp"

//Функции-шаблоны

 template <class T> inline void Swap(T&a,T&b)

{T c;

 c=a,a=b,b=c;

 }

 template <class T>T Max(T *a,int n)

 {int i;T max=a[0];

  for(i=1;i<n;i++)

  if(a[i]>max)max=a[i];

  return max;

  }

template <class T> void Bul_bul(T *a,int n)

//улучшенный «пузырек» с флагом f

{int i,j,f;

 for(i=0,f=1;i<n-1&&f;i++)

  for(j=0,f=0;j<n-i-1;j++)

  if(a[j]>a[j+1]){Swap(a[j],a[j+1]);f=1;}

//  {c=a[j];a[j]=a[j+1];a[j+1]=c;f=1;}

  }

template <class X,class Y>  void out2(X  a,Y  b)

  {cout<<a<<' '<<b;

  }

Как же будет работать компилятор?

При вызове функций-шаблонов в зависимости от типов фактических аргументов компилятор создает различные версии каждой из этих функций. Говорят, что компилятор создает порожденную функцию. Процесс генерации порожденной функции называют созданием экземпляра функции. Таким образом, порожденная функция – это конкретный экземпляр функции-шаблона.