Как отмечено в комментариях, при вызове функции swapargs(i, j) выполняется явно перегруженная версия функции swapargs(), определенная в программе. Компилятор в этом случае не генерирует эту версию обобщенной функции swapargs(), поскольку обобщенная функция переопределяется явно заданным вариантом перегруженной функции.

Для обозначения явной специализации функции можно использовать новый альтернативный синтаксис, содержащий ключевое слово template. Например, если задать специализацию с использованием этого альтернативного синтаксиса, перегруженная версия функции swapargs() из предыдущей программы будет выглядеть так.

// Использование нового синтаксиса задания специализации.

template<>

void swapargs (int &a, int &b)

{

 int temp;

 temp = a;

 a = b;

 b = temp;

 cout << "Это int-специализация функции swapargs.\n";

}

Как видите, в новом синтаксисе для обозначения специализации используется конструкция template<>. Тип данных, для которых создается эта специализация, указывается в угловых скобках после имени функции. Для задания любого типа обобщенной функции используется один и тот же синтаксис. На данный момент ни один из синтаксических способов задания специализации не имеет никаких преимуществ перед другим, но с точки зрения перспективы развития языка, возможно, все же лучше использовать новый стиль.

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

Перегрузка шаблона функции

Помимо создания явным образом перегруженных версий обобщенной функции, можно также перегружать саму спецификацию шаблона функции. Для этого достаточно создать еще одну версию шаблона, которая будет отличаться от остальных списком параметров. Рассмотрим пример.

// Объявление перегруженного шаблона функции.

#include

using namespace std;

// Первая версия шаблона f().

template

void f(X a)

{

 cout << "Выполняется функция f(X a)\n";

}

// Вторая версия шаблона f().

template

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

using namespace std;

// Отображение данных заданное количество раз.

template

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)

{

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

Все книги серии Изучайте C++ с профессионалами

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