Если вместо макроса препроцессора min() подставить в текст предыдущей программы этот шаблон, то результат будет правильным:

elem_cnt : 10 expecting: 10

(В стандартной библиотеке C++ есть шаблоны функций для многих часто используемых алгоритмов, например для min(). Эти алгоритмы описываются в главе 12. А в данной вводной главе мы приводим собственные упрощенные версии некоторых алгоритмов из стандартной библиотеки.)

Как объявление, так и определение шаблона функции всегда должны начинаться с ключевого слова template, за которым следует список разделенных запятыми идентификаторов, заключенный в угловые скобки '' и '', – список параметров шаблона, обязательно непустой. У шаблона могут быть параметры-типы, представляющие некоторый тип, и параметры-константы, представляющие фиксированное константное выражение.

Параметр-тип состоит из ключевого слова class или ключевого слова typename, за которым следует идентификатор. Эти слова всегда обозначают, что последующее имя относится к встроенному или определенному пользователем типу. Имя параметра шаблона выбирает программист. В приведенном примере мы использовали имя Type, но могли выбрать и любое другое:

template class Glorp

Glorp min2( Glorp a, Glorp b ) {

return a b ? a : b;

}

При конкретизации (порождении конкретного экземпляра) шаблона вместо параметра-типа подставляется фактический встроенный или определенный пользователем тип. Любой из типов int, double, char*, vectorint или listdouble является допустимым аргументом шаблона.

Параметр-константа выглядит как обычное объявление. Он говорит о том, что вместо имени параметра должно быть подставлено значение константы из определения шаблона. Например, size – это параметр-константа, который представляет размер массива arr:

template class Type, int size

Type min( Type (arr) [size] );

Вслед за списком параметров шаблона идет объявление или определение функции. Если не обращать внимания на присутствие параметров в виде спецификаторов типа или констант, то определение шаблона функции выглядит точно так же, как и для обычных функций:

template class Type, int size

Type min( const Type (r_array)[size] )

{

/* параметризованная функция для отыскания

* минимального значения в массиве */

Type min_val = r_array[0];

for ( int i = 1; i size; ++i )

if ( r_array[i] min_val )

min_val = r_array[i];

return min_val;

}

В этом примере Type определяет тип значения, возвращаемого функцией min(), тип параметра r_array и тип локальной переменной min_val; size задает размер массива r_array. В ходе работы программы при использовании функции min() вместо Type могут быть подставлены любые встроенные и определенные пользователем типы, а вместо size – те или иные константные выражения. (Напомним, что работать с функцией можно двояко: вызвать ее или взять ее адрес).

Процесс подстановки типов и значений вместо параметров называется конкретизацией шаблона. (Подробнее мы остановимся на этом в следующем разделе.)

Список параметров нашей функции min() может показаться чересчур коротким. Как было сказано в разделе 7.3, когда параметром является массив, передается указатель на его первый элемент, первая же размерность фактического аргумента-массива внутри определения функции неизвестна. Чтобы обойти эту трудность, мы объявили первый параметр min() как ссылку на массив, а второй – как его размер. Недостаток подобного подхода в том, что при использовании шаблона с массивами одного и того же типа int, но разных размеров генерируются (или конкретизируются) различные экземпляры функции min().

Имя параметра разрешено употреблять внутри объявления или определения шаблона. Параметр-тип служит спецификатором типа; его можно использовать точно так же, как спецификатор любого встроенного или пользовательского типа, например в объявлении переменных или в операциях приведения типов. Параметр-константа применяется как константное значение – там, где требуются константные выражения, например для задания размера в объявлении массива или в качестве начального значения элемента перечисления.

// size определяет размер параметра-массива и инициализирует

// переменную типа const int

template class Type, int size

Type min( const Type (r_array)[size] )

{

const int loc_size = size;

Type loc_array[loc_size];

// ...

}

Перейти на страницу:

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