Предоставлено также значение по умолчанию для этого параметра шаблона и соответствующего ему параметра функции. Аргумент шаблона по умолчанию определяет, что функция compare()
будет использовать библиотечный класс less
объекта функции, экземпляр которого создается с тем же параметром типа, что и функция compare()
. Заданный по умолчанию аргумент функции указывает, что параметр f
будет инициализирован по умолчанию объектом типа F
.
Когда пользователи вызывают эту версию функции compare()
, они могут предоставить собственный оператор сравнения, но не обязаны делать это:
bool i = compare(0, 42); //
//
Sales_data item1(cin), item2(cin);
bool j = compare(item1, item2, compareIsbn);
Первый вызов использует заданный по умолчанию аргумент функции, которым является объект типа less
. В этом вызове Т
имеет тип int
, поэтому у объекта будет тип less
. Этот экземпляр функции compare()
будет использовать для сравнения тип less
.
Во втором вызове передается функция compareIsbn()
(см. раздел 11.2.2) и два объекта типа Sales_data
. Когда функция compare()
вызывается с тремя аргументами, типом третьего аргумента должен быть вызываемый объект, возвращающий тип, приводимый к типу bool
и получающий аргументы типа, совместимого с типами первых двух аргументов. Как обычно, типы параметров шаблона выводятся из соответствующих им аргументов функции. В этом вызове тип T
выводится как тип Sales_data
, а тип F
— как тип compareIsbn()
.
Как и с аргументами функций по умолчанию, у параметра шаблона может быть аргумент по умолчанию, только если у всех параметров справа от него также есть аргументы по умолчанию.
Всякий раз, когда используется шаблон класса, за именем шаблона всегда должны следовать угловые скобки. Скобки означают, что класс будет создан как экземпляр шаблона. В частности, если шаблон класса предоставляет аргументы по умолчанию для всех своих параметров и следует использовать именно их, то после имени шаблона следует поместить пустую пару угловых скобок:
template
public:
Numbers(Т v = 0): val(v) { } //
private:
Т val;
};
Numbers
Numbers<> average_precision; //
Здесь создаются два экземпляра шаблона Numbers
: версия average_ precision
— экземпляр Numbers
с заменой параметра Т
типом int
; версия lots_of_precision
— экземпляр Numbers
с заменой параметра Т
типом long double
.
Упражнение 16.17. Каковы (если есть) различия между параметром типа, объявленным с ключевым словом typename
и ключевым словом class
? Когда должно использоваться ключевое слово typename
?
Упражнение 16.18. Объясните каждое из следующих объявлений шаблона функции и укажите, допустимы ли они. Исправьте все найденные ошибки.
(a) template
(b) template
(c) inline template
(d) template
(e) typedef char Ctype;
template
Упражнение 16.19. Напишите функцию, получающую ссылку на контейнер и выводящую его элементы. Используйте переменную size_type
и функцию-член size()
контейнера для контроля цикла, вывода элементов.
Упражнение 16.20. Перепишите функцию из предыдущего упражнения так, чтобы использовать для контроля цикла итераторы, возвращаемые функциями begin()
и end()
.
У класса (обычного или шаблона класса) может быть функция-член, которая сама является шаблоном. Такие члены называются