Шаблоны

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

В приведенном ниже листинге нет необходимости в знании типа, необходимо только существование операций >, = над множеством данных.

Листинг: пример шаблона сортировки

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;
            }
        }
    }
}
exswap.cpp
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