518_______________________Часть III. Современное программирование на C++
Использование в функциях-шаблонах таких операций, как присваивание (=), проверка на равенство (==) и других сравнений также требует дополнительного внимания. Обязательно задайтесь вопросом: "Имеет ли смысл эта операция?" и "Допустимы ли присваивание или сравнение этих величин?"
Например, в случае функции Swap с параметрами типа char* изменяются адреса, содержащиеся в указателях. Это буквальное копирование. Но если вы собираетесь проверять эквивалентность значений данных, то проверять равенство адресов вам, разумеется, ни к чему. Это особенно существенно для сложных типов данных, поскольку они не располагают встроенными средствами сравнения.
Конкретизация шаблонов
Реализация конкретной функции-шаблона может быть модифицирована в соответствии с нуждами конкретного типа данных. То есть если конкретный тип данных не поддерживается вашей общей реализацией, то для этого типа можно написать специальную версию. Рассмотрим функцию, которая проверяет, является ли левый аргумент большим из двух аргументов. Напишем встраиваемую функцию-шаблон с именем isGreater() как функцию, которая принимает ссылки на два аргумента и для сравнения аргументов использует операцию >:
template <class T> inline int IsGreaterf T& a, T<i b) { return a > b ? 1 : 0; }
К сожалению, если попробовать сравнить по этому алгоритму две строки, завершаемые нулем, то большей будет считаться строка с большим значением адреса памяти.
Чтобы построить корректный алгоритм для строк ASCIIZ, напишем специальную версию функции для работы с типом char*, использующую функцию stronp. Эта функция возвращает положительное значение в случае, если левая строка больше правой. Вот как выглядит эта специальная версия:
#include <string.h> // здесь содержится объявление
// функции strcrnp (сравнение строк) // inline int IsGreater( char* a, char* b) тоже работает! inline int IsGreater<char*>( char* S a, char* & b) ( return stronpt a, b) > 0 ? 1 : 0; }
Из главы 15 известно, что C++ допускает перегрузку функций. 1^ функциям-шаблонам перегрузка функций также применима. Из нашей демонстрационной программы видно, что для тех типов данных, которые не подходят для общей версии, можно построить специальную реализацию. В листинге 19.2 приведен полный текст программы, которая иллюстрирует работу с шаблонами и перегрузку шаблонов.