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). |