Предоставлено также значение по умолчанию для этого параметра шаблона и соответствующего ему параметра функции. Аргумент шаблона по умолчанию определяет, что функция compare() будет использовать библиотечный класс less объекта функции, экземпляр которого создается с тем же параметром типа, что и функция compare(). Заданный по умолчанию аргумент функции указывает, что параметр f будет инициализирован по умолчанию объектом типа F.

Когда пользователи вызывают эту версию функции compare(), они могут предоставить собственный оператор сравнения, но не обязаны делать это:

bool i = compare(0, 42); // использует less; i равно -1

// результат зависит от isbn в item1 и item2

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 class Numbers { // по умолчанию Т - это int

public:

 Numbers(Т v = 0): val(v) { } // различные операции с числами

private:

 Т val;

};

Numbers lots_of_precision;

Numbers<> average_precision; // пустые <> означают тип по умолчанию

Здесь создаются два экземпляра шаблона Numbers: версия average_ precision — экземпляр Numbers с заменой параметра Т типом int; версия lots_of_precision — экземпляр Numbers с заменой параметра Т типом long double.

Упражнения раздела 16.1.3

Упражнение 16.17. Каковы (если есть) различия между параметром типа, объявленным с ключевым словом typename и ключевым словом class? Когда должно использоваться ключевое слово typename?

Упражнение 16.18. Объясните каждое из следующих объявлений шаблона функции и укажите, допустимы ли они. Исправьте все найденные ошибки.

(a) template void f1(T, U, V);

(b) template T f2(int &T);

(c) inline template T foo(T, unsigned int*);

(d) template f4(T, T);

(e) typedef char Ctype;

     template Ctype f5(Ctype a);

Упражнение 16.19. Напишите функцию, получающую ссылку на контейнер и выводящую его элементы. Используйте переменную size_type и функцию-член size() контейнера для контроля цикла, вывода элементов.

Упражнение 16.20. Перепишите функцию из предыдущего упражнения так, чтобы использовать для контроля цикла итераторы, возвращаемые функциями begin() и end().

<p>16.1.4. Шаблоны-члены</p>

У класса (обычного или шаблона класса) может быть функция-член, которая сама является шаблоном. Такие члены называются шаблонами-членами (member template). Шаблоны-члены не могут быть виртуальными.

Шаблоны-члены обычных (не шаблонных) классов
Перейти на страницу:

Похожие книги