Перше звернення до функції max генерує функцію
const String& max(const String& а, const String& b);
Другий обіг генерує функцію
const int& max(const int& а, const int& b);
Оголошення шаблона функції max говорить, що конкретна функція залежить від одного параметра - типа Т. Перше звернення до max в програмі використовує аргументи типу string. В шаблон функції підставляється тип String замість Т. Виходить функція:
const Strings max(const Strings а, const Strings, b)
{
if (а > b)
return а; else
return b;
}
Ця функція компілюється і використовується в програмі. Аналогічні дії відбуваються і при другому зверненні, тільки тепер замість параметра Т підставляється тип int. Як видно з наведених прикладів, компілятор сам визначає, яку функцію треба використовувати і автоматично генерує необхідне визначення.
У функції-шаблона може бути декілька параметрів. Так, наприклад, функція find бібліотеки STL (стандартної бібліотеки шаблонів), яка шукає перший елемент, рівний заданому, в інтервалі значень, має вигляд:
template <class Inlterator, class T>
Inlterator
find(Inlterator first, Inlterator last, const TS val);
Клас Т - це тип елементів інтервалу. Тип Inlterator - тип покажчика на початок і кінець інтервалу.
Не завжди шаблонна функція може бути ефективно застосована до всіх передбачених типів даних. В цьому випадку ніщо не заважає вам визначити спеціалізований варіант цієї функції для якогось типу параметрів. Наприклад, розглянута вище шаблонна функція
template <class T>
const T& max(const T& а, const T& b)
непридатна для використовування з масивами символів. В цьому випадку можна визначити спеціалізовану версію функції. Наступний приклад це демонструє:
#include <iostream>
#include <cstring>
//Повертає більший з двох параметрів
template <class T>
const Т& max(const T& а, const T& b)
{
return а > b ? а : b;
}
char* max(char* strl, char* str2)
{
return strcmp(strl, str2) >= 0 ?
strl : str2;
}
void main()
{
int m = 9, n = 12;
char* str1 = "слово і справа" ;
char* str2 = "слово і cправа" ;
cout « "max int = " « max (m, n);
cout « "max str = " « max (strl, str2);
}
Зустрівши виклик функції, компілятор використовує наступний алгоритм для дозволу посилання:
знайти звичайну (нешаблонну) функцію, типи параметрів якої в точності відповідають вказаним у виклику;
якщо функція не знайдена, знайти шаблонну функцію, яка породжує функцію, типи параметрів якої в точності відповідають вказаним у виклику;
якщо така шаблонна функція не знайдена, знову почати пошук звичайної функції, параметри якої можна перетворити до заданих при виклику.
2 Оголошення шаблону класів та визначення його методів
Окрім шаблонів функцій, можна оголошувати і шаблони класів.
Шаблон класу є узагальненим визначенням класу, що включає типи даних як параметри, з якого компілятор автоматично створює клас для заданих користувачем типів даних. Коли компілятор створює за шаблоном класу конкретний клас для певних користувачем типів даних, то говорять, що він створив породжений клас. У зв’язку з цією обставиною шаблон класу називають іноді родовим класом. Синтаксис оголошення шаблона класу має наступний вигляд:
template <class T1 ідентифікатор1, T2 ідентифікатор2,..., TN ідентифікаторN>
class ім’я класу
{
//тіло класу
}
За ключовим словом template записують один або декілька параметрів, вкладених в кутові дужки, розділені між собою комами. Кожний параметр є:
або ключовим словом class, за яким записують ім’я типу;
або ім’ям типа, за яким записують ідентифікатор.
Потім іде оголошення класу. Оголошення і визначення класу використовують список параметрів шаблона. Для завдання типів даних, що параметризуються, замість ключового слова class в кутових дужках може також використовуватися ключове слово typename. Як і у разі шаблонних функцій, ключове слово class або typename показує, що параметр представляє або вбудований, або визначений користувачем тип даних. Параметри шаблона, наступні за ключовим словом class або typename, називають типами, що параметризуються. Параметри шаблона, що складаються з імені типу і наступного за ним ідентифікатора, інформують компілятор про те, що параметром шаблона є константа вказаного типу. У зв’язку з цим такі параметри називаються нетиповими. Ім’я формального параметра в списку параметрів шаблона класу повинне бути унікальним.
