Явная специализация шаблона позволяет спроектировать версию обобщенной функции в расчете на некоторую уникальную ситуацию, чтобы, возможно, воспользоваться преимуществами повышенного быстродействия программы только для одного типа данных. Но, как правило, если вам нужно иметь различные версии функции для разных типов данных, имеет смысл использовать перегруженные функции, а не шаблоны.
Помимо создания явным образом перегруженных версий обобщенной функции, можно также перегружать саму спецификацию шаблона функции. Для этого достаточно создать еще одну версию шаблона, которая будет отличаться от остальных списком параметров. Рассмотрим пример.
// Объявление перегруженного шаблона функции.
#include <iostream>
using namespace std;
// Первая версия шаблона f().
template <class X>
void f(X a)
{
cout << "Выполняется функция f(X a)\n";
}
// Вторая версия шаблона f().
template <class X, class Y>
void f(X a, Y b)
{
cout << "Выполняется функция f(X a, Y b)\n";
}
int main()
{
f(10); // Вызывается функция f(X).
f(10, 20); // Вызывается функция f(X, Y).
return 0;
}
Здесь шаблон для функции f() перегружается, чтобы обеспечить возможность приема как одного, так и двух параметров.
В шаблонных функциях можно смешивать стандартные параметры с обобщенными параметрами типа. Эти параметры работают так же, как в любой другой функции. Рассмотрим пример.
// Использование стандартных параметров в шаблонной функции.
#include <iostream>
using namespace std;
// Отображение данных заданное количество раз.
template<class Х>
void repeat(X data, int times)
{
do {
cout << data << "\n";
times--;
}while(times);
}
int main()
{
repeat("Это тест.", 3);
repeat(100, 5);
repeat(99.0/2, 4);
return 0;
}
Вот какие результаты генерирует эта программа.
Это тест.
Это тест.
Это тест.
100
100
100
100
100
49.5
49.5
49.5
49.5
В этой программе функция repeat() отображает свой первый аргумент столько раз, сколько задано ее вторым аргументом. Поскольку первый аргумент имеет обобщенный тип, функцию repeat() можно использовать для отображения данных любого типа. Параметр times — стандартный, он передается по значению. Смешанное задание обобщенных и необобщенных параметров, как правило, не вызывает никаких проблем и является обычной практикой программирования.
Обобщенные функции подобны перегруженным функциям, но имеют больше ограничений по применению. При перегрузке функций в теле каждой из них обычно задаются различные действия. Но обобщенная функция должна выполнять одно и то же действие для всех версий — отличие между версиями состоит только в типе данных. Рассмотрим пример, в котором перегруженные функции нельзя заменить обобщенной функцией, поскольку они выполняют различные действия,
void outdata(int i)