223.50K
Категория: ПрограммированиеПрограммирование

Шаблоны функций

1.

ШАБЛОНЫ ФУНКЦИЙ
Шаблоны дают возможность определять при
помощи одного фрагмента кода целый набор
взаимосвязанных функций (перегруженных),
называемых шаблонными функциями.
Например, можно написать один шаблон
функции сортировки массива, на основе
которого
C++
будет
автоматически
генерировать отдельные шаблонные функции,
сортирующие массивы типов int, float, массив
строк и т.д.

2.

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

3.

Все описания шаблонов функций начинаются с
ключевого слова template, за котором следует
список формальных параметров шаблона,
заключаемый в угловые скобки (< и >); каждому
формальному
параметру
должно
предшествовать ключевое слово class или
typename.
Например,
template <class T>
template <typename ElementType>
template <class BorderType, class FillType>

4.

Формальные параметры в описании шаблона
используются
(наряду
с
параметрами
встроенных типов или типов, определяемых
пользователем)
для
определения
типов
параметров функции, типа возвращаемого
функцией значения и типов переменных,
объявляемых внутри функции.
Ключевое
слово
class
или
typename,
используемое в шаблоне функции при задании
типов
параметров,
означает
«любой
встроенный тип или тип, определяемый
пользователем».

5.

Далее, за этим заголовком, следует обычное
описание функции.
Замечание. Ошибкой является отсутствие
ключевого слова class (или typename) перед
каждым
формальным
параметром
типа
шаблона функции.
Пример. Объявление и вызов шаблонной
функции.
#include <iostream>
using namespace std;
template <class T>
T inc_value(T val) {
++val;
return val; }

6.

int main() {
int x = 0;
Float y = 0;
y=inc_value(x);
cout<<x<<endl;
char c = 13;
c=inc_value(c);
cout<<c<<endl;
return 0;
}T называется параметром типа.
Когда компилятор обнаруживает в тексте
программы вызов функции inc_value(), он
заменяет T во всей области определения
функции на указанный при вызове тип.

7.

Таким образом С++ создает вариант шаблонной
функции с указанным типом.
После этого вновь
компилируется.
созданная
функция
Пример. Объявление и вызов шаблонной
функции для вывода массива.
#include <iostream>
using namespace std;

8.

template <class T>
void PrintArray(const T* array, const int count) {
for (int i=0; i<count; i++)
cout<<array[i]<<" ";
cout<<endl;
int main(){
const int aCount=5, bCount=7, cCount=6;
int a[aCount]={1,2,3,4,5};
double b[bCount] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6,
7.7};
char c[cCount]="HELLO";

9.

PrintArray(a,aCount);
PrintArray(b,bCount);
PrintArray(c,cCount);
return 0;
}

10.

Шаблоны функций расширяют возможности
многократного использования программного
кода.
В примере шаблонная функция заменила 4
обычных:
void PrintArray(const int*, const int);
void PrintArray(const double*, const int);
void PrintArray(const char*, const int);
Замечание. Программа может создавать
слишком много копий шаблонных функций и
шаблонных классов, для хранения которых
могут потребоваться значительные ресурсы
памяти.

11.

Перегрузка шаблонных функций
Компилятор использует механизм перегрузки
для того, чтобы обеспечить работу с
шаблонами функций.
Шаблон функции можно перегружать:
1) шаблоном
параметров;
функции
с
другим
набором
2) нешаблонной функцией с указанием точных
типов параметров.

12.

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

13.

3) если такого шаблона нет, то выводится
сообщение об ошибке.
Пример.
Использование
перегруженных
шаблонов функций и нешаблонных функций
template <class T>
void PrintArray(T* , int count) {...}
void PrintArray(char* array, int count) {
for (int i=0; i<count; i++)
cout<<array[i]<<endl;
}

14.

template <class T>
void PrintArray(T*, int lowSubscript,
highSubscript) {
for (int i=lowSubscript; i<=highSubscript; i++)
cout<<array[i]<<" ";
cout<<endl;
}
int main() {
const int aCount=5, bCount=7, cCount=6;
int a[aCount]={...};
double b[bCount] = {...};
char c[cCount]="HELLO";
int

15.

PrintArray(a,aCount);
//генерируется
шаблонная функция void PrintArray(const int*
array, const int count) на основе первого
шаблона
PrintArray(b,2,5); //генерируется шаблонная
функция PrintArray(const double* array, const int
lowSubscript, const int highSubscript) на основе
второго шаблона

16.

PrintArray(c,cCount);
нешаблонная функция
array, const int count)
return 0;
}
//
void
вызывается
PrintArray(char*
Замечание.
Компилятор
ищет
шаблон,
полностью
соответствующий
вызываемой
функции
по
типу
всех
параметров;
автоматическое преобразование типов не
производится (возможно, char к int, double к int и
т.д.).
English     Русский Правила