Шаблоны
STL — это библиотека
шаблонов. Прежде всего вспомним, что такое шаблон. Различают шаблоны функций
и шаблоны классов. Шаблон функций (function template) является средством языка
C++, позволяющим избежать рутинного переписывания кодов функций, которые имеют
сходный алгоритм, но разные типы параметров. Классическим примером, иллюстрирующим
выгоды шаблона, является множество реализаций функции max (a, b) . При отсутствии
механизма шаблонов для придания функции max () универсального характера следует
создать несколько функций, разделяющих одно и то же имя. Например:
long
max
(long a,
long b);
double
max
(double a, double b);
MyType
max (mytype a, mytype b);
Vectors
max (Vectors a, Vectors b);
Очевидно, что
тела всех функций могут выглядеть совершенно одинаково для многих типов параметров.
Например, коды функции max могут иметь вид:
return
(a>b) ? а :
b;
В таких случаях
удобно использовать шаблон функции. Шаблон задается ключевым словом template:
template <class Т> Т max(Т х, Т у)
{
return (х>у) ? х : у;
};
Описатель <class
т> — это аргумент шаблона. Символ т (type) означает произвольный тип данных
т, который будет задан при использовании шаблона, т выполняет роль формального
параметра, поэтому сам символ (т) может быть и другим, но везде одинаковым.
При фактическом использовании шаблона место т заменяет какой-то уже описанный
тип. Им может быть как стандартный, встроенный тип языка, так и новый тип, определенный
пользователем. В том числе он может быть именем класса, определенного ранее.
Важно, чтобы для типа был определен смысл операции > (больше). Если т заменяется
классом, то в классе должна быть предварительно реализована операция operator>
().
Примечание
Не идите на поводу у ложного друга — переводчика термина operator. В английском языке он имеет смысл операции (например, операция + или операция <, операция логического или |, и т. д.). То, что мы называем оператором языка (например, оператор while, оператор for, условный оператор if, и т. д.), имеет английский аналог — statement (например, conditional statement if).
Если задан
шаблон, то компилятор генерирует подходящие коды функции max () в соответствии
с конкретными типами фактических параметров, использованных при вызове функции.
Например, встретив во внешней функции коды:
Man
a("Alex Black", 54), b("Galina Black", 44), с;
с
= max (a, b);
cout
« "\n Старший: " « с;
компилятор
в сгенерированной по шаблону копии функции max при сравнении объектов класса
Man использует функцию operator > (), которая должна быть определена внутри
класса Man. Например, так:
int
operator
>(Man&
m) {
return
m__Age > m. m_Age; }
Если в той
же внешней функции встретится оператор:
cout
« "\n max (10,011) = " « max (10,011);
то компилятор
в другой копии функции max, сгенерированной по тому же шаблону, использует операцию
>, определенную для стандартного типа данных int. Один раз написав шаблон
функции max, мы можем вызывать ее для всех типов данных, для которых определена
операция operator> (). Если для какого-то типа
данных
тело функции max не годится, то можно отменить (override) действие шаблона функции
для этого типа. Например, определив функцию:
char* max (char* s, char *t)
{
return (strcmp (s, t) >0) ?s : t;
}
мы отменяем
действие шаблона для символьных строк, так как функция, скроенная по шаблону,
осуществляла бы ничего не значащее сравнение указателей s и t. При использовании
шаблона следует строго соблюдать типы параметров и не надеяться на стандартные
преобразования типов, по умолчанию осуществляемые компилятором при вызове обычных
функций. Например, явно заданную функцию, скрывающую (отменяющую) шаблон:
double
max (double, double);
можно вызывать
с аргументами (int, double) или (float, long). Компилятор при этом автоматически
преобразует параметры к типу double. Однако если явная декларация функции, скрывающей
шаблон, отсутствует, то шаблон
template
<class T> T max(Т х, Т у)
не позволит смешивать типы при вызове функции max. Таким образом, обращение int i=max (9, 8.); вызывает сообщение об ошибке: "Could not find a match for max (int, double) ", которое означает, что не найдена функция max () для пары аргументов типа (int, double).