Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Билеты по ООП.doc
Скачиваний:
4
Добавлен:
14.04.2019
Размер:
596.48 Кб
Скачать

40. Функции-шаблоны

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

Функции-шаблоны создаются с использованием ключевого слова template (шаблон). Шаблон используется для создания каркаса функции, оставляя компилятору реализацию подробностей. Общая форма функции-шаблона имеет следующий вид:

template<class Т> возвращаемый_тип имя_функции(список параметров)

{

// тело функции

}

Здесь Т является параметром-типом, «держателем места» для имени типа данных, которое используется функцией. Этот параметр-тип может быть использован в определении функции. Он будет автоматически заменён компилятором на фактический тип данных во время создания конкретной версии функции.

Листинг 1

// пример шаблона функции

#include <iostream>

using namespace std;

// шаблон функции

template <class X> void Swap(X &a, X &b)

{

X temp;

temp=a;

a=b;

b=temp;

}

int main()

{

int i=10, j=20;

double x=10.1, y=23.3;

char a='x', b='z';

cout<<"Original i, j: "<< i << " " << j << "\n";

cout<<"Original x, y: "<< x << " " << y << "\n";

cout<<"Original a, b: "<< a << " " << b << "\n";

Swap(i, j);

Swap(x, y);

Swap(a, b);

cout<<"Swapped i, j: " << i << " " << j << "\n";

cout<<"Swapped x, y: " << x << " " << y << "\n";

cout<<"Swapped a, b: " << a << " " << b << "\n";

return 0;

}

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

Листинг 2

#include <iostream>

using namespace std;

template <class type1, class type2> void myfunc(type1 x, type2 y)

{

cout << x << " " << y << endl;

}

int main()

{

myfunc(10, "hi");

myfunc(0.23, 10L);

return 0;

}

Явная перегрузка функций-шаблонов

Хотя функция-шаблон перегружает себя по мере необходимости, также можно перегрузить её явным образом. Если перегружается функция – шаблон, то перегруженная функция переопределяет функцию шаблон для того конкретного набора типов параметров, для которых создаётся перегруженная функция. В качестве примера рассмотрим следующую версию функции swap().

Листинг 3

// перегрузка функции-шаблона

#include <iostream>

using namespace std;

// шаблон функции

template <class X> void Swap(X &a, X &b)

{

X temp;

temp=a;

a=b;

b=temp;

}

// отдельная версия Swap()

void Swap(int &a, int &b)

{

int temp;

temp=a;

a=b;

b=temp;

cout << "Inside overloaded Swap().\n";

}

int main()

{

int i=10, j=20;

double x=10.1, y=23.3;

char a='x', b='z';

cout << "Original i, j: " << i << " " << j << "\n";

cout << "Original x, y: " << x << " " << y << "\n";

cout << "Original a, b: " << a << " " << b << "\n";

Swap(i, j);

Swap(x, y);

Swap(a, b);

cout << "Swapped i, j: " << i << " " << j << "\n";

cout << "Swapped x, y: " << x << " " << y << "\n";

cout << "Swapped a, b: " << a << " " << b << "\n";

return 0;

}

Ограничения на функции-шаблоны

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

Пример (перегруженные функции не могут быть заменены на функцию-шаблон)

#include <iostream>

#include <math.h>

using namespace std;

void myfunc(int i)

{

cout << "value is: " << i << "\n";

}

void myfunc(double d)

{

double intpart;

double fracpart;

fracpart = modf(d, &intpart);

cout << "fractional part: " << fracpart;

cout << "\n";

cout << "Integer part: " << intpart;

}

int main()

{

myfunc(1);

myfunc(12.2);

return 0;

}

Другим ограничением на классы-шаблоны является то, что виртуальная функция не может быть функцией-шаблоном.