Шаблоны
Механизм шаблонов в языке С++ позволяет решать проблему унификации алгоритма для различных типов: нет необходимости писать различные функции для целочисленных, действительных или пользовательских типов – достаточно составить обобщенный алгоритм, не зависящий от типа данных, основывающийся только на общих свойствах. Например, алгоритм сортировки может работать как с целыми числами, так и с «автомобилями».
В приведенном ниже листинге нет необходимости в знании типа, необходимо только существование операций >, = над множеством данных.
Листинг: пример шаблона сортировки
template<typename T>
void sort(T* v, size_t length){
size_t i = 0,
j = 0;
for(; i != length - 1; ++i){
for(j = i + 1; j != length; ++j){
if(v[i] > v[j]){
T tmp = v[i];
v[i] = v[j];
v[j] = tmp;
}
}
}
}
template<class TYPE>
void swap(TYPE& p1, TYPE& p2){
TYPE tmp = p1;
p1 = p2;
p2 = tmp;
}
Существуют шаблоны функций и шаблоны классов. Шаблоны функций – это обобщенное описание поведения функций, которые могут вызываться для объектов разных типов. Другими словами, шаблон функции представляет собой семейство разных функций. По описанию шаблон функции похож на обычную функцию; разница в том, что некоторые элементы не определены (типы, константы) и являются параметризованными.
Шаблоны классов – обобщенное описание пользовательского типа, в котором могут быть параметризованы атрибуты и операции типа. Представляют собой конструкции, по которым могут сгенерированы действительные классы путём подстановки вместо параметров конкретных аргументов.
Статический полиморфизм
Использование шаблонов в программе удовлетворяют описанию полиморфизма – одна и та же форма записи одинаково работает для различных типов данных. Данное свойство называется статическим полиморфизмом, потому что определение поведения шаблонной функции выполняется на этапе компиляции программы. Вызов шаблона функции из примера `exswap.cpp`` эквивалентен вызову функции: swap(a, b); - в этом случае компилятор определит подставляемый тип в шаблон по типам параметров и сгенерирует необходимую функцию на основе шаблона. В случае вызова шаблона с другими типами параметров, компилятор создаст новую версию функции swap. Возможно и явное указание типов - swap<int>(a, b); Эта возможность полезна в том случае, когда переменные a и b имеют различные, но совместимые типы. Обратите внимание на пример.
int main(){
int i1 = 3, i2 = 5;
float f1 = 1.2, f2 = 2.3;
double d1 = 1.003, d2 = 10;
swap(i1, i2);
swap(f1, f2);
swap(d1, d2);
return 0;
}
Как видно, одно и то же имя функции используется с различными типами данных. Данное свойство называется статическим полиморфизмом, потому что определение поведения функции выполняется на этапе компиляции программы, в отличие от динамического полиморфизма на основе виртуальных функций.
Если же в программе swap не используется, то в скомпилированную программу не будет добавлен бинарный код функции swap.
Специализация шаблонов
Шаблоны функций и классов представляют решение некоторой задачи в общем виде. Однако в некоторых случаях более эффективным будет частное решение. В этом случае программист может описать частное решение для конкретного случая.
template<>
void swap(int* a, int* b){
int tmp = *a;
*a = *b;
*b = tmp;
}
Last updated