Для знакомства с шаблонами функций (см. п. п. 14.5.5 в [1]) напишем шаблон функции суммирования последовательности элементов массива. Параметром шаблона можно сделать, очевидно, тип элементов массива, а параметрами функции
будут, как обычно, два указателя: указатель на первый суммируемый элемент последовательности и указатель на первый элемент, не включаемый в сумму. Напомню, этот подход принят в стандартной библиотеке шаблонов1, и мы тоже уже применяли подобный подход при реализации конструкторов классов TString (см. листинг 4.2) и ТАггау (см. листинг 5.4). Шаблон функции суммирования представлен в листинге 12.1.
Листинг 12.1. Шаблон функции суммирования элементов массива
template <typename Т>
Т Summa(T const *begin, Т const *end)
{ T total = T(); // инициализация нулем
while (begin != end)
{ total +=*begin; ++begin;
}
return total;
}
Как видно, шаблон функции так же, как и метод класса, должен начинаться с заголовка шаблона, в котором задаются его параметры. После заголовка следует обычное определение функции, в котором на месте типа стоит имя параметра-типа. Обнуление переменной для суммирования осуществляется с помощью уже известной нам конструкции инициализации нулем. Использовать данный шаблон можно следующим образом:
int а[10]= {1,2,3.4,5,6,7.8,9,10};
cout << Summa(a, а+10) << endl; // суммирование массива типа int
double b[10]= {1.1,2,3,4,5,6,7,8,9,10.1};
cout << Summa(b, b+10) << endl; // суммирование массива типа double
Сразу бросается в глаза, что при вызове шаблона функции не заданы аргументы шаблона в угловых скобках о — вызов функции-шаблона не отличается от вызова обычной функции. В этом состоит принципиальное отличие шаблонов функций от шаблонов классов — для шаблонов классов аргументы нужно задавать всегда явно. В данном случае компилятор самостоятельно выводит подставляемый тип на основании информации о типе фактического аргумента при вызове.
В случае инстанцирования шаблона при первом вызове (для массива int а [ 10]) компилятор генерирует конкретный вариант функции:
int Summa(int const *begin, int const *end)
{ int total = int(); // инициализация нулем
while (begin != end)
{ total +=*begin; ++begin;
}
return total;
В стандартной библиотеке параметры — это итераторы, частным случаем которых являются указатели. |