Основные принципы и понятия при работе с шаблоном.
Теперь, после поверхностного знакомства - мы рассмотрим все особенности работы шаблонов:
1. При определении шаблона используются два спецификатора: template и typename.
2. На место параметра типа Т можно подставить любое корректное имя.
3. В угловые скобки можно записывать больше одного параметра типа.
4. Параметр функции - это значение, передаваемое в функцию при выполнении программы.
5. Параметр типа - указывает тип аргумента, передаваемого в функцию, и обрабатывается только при компиляции.
Процесс компиляции шаблона.
1. Определение шаблона не вызывает генерацию кода компилятором самостоятельно. Последний создает код функции только в момент её вызова и генерирует при этом соответствующую версию функции.
2. Следующий вызов с теми же типами данных параметров не спровоцирует генерацию дополнительной копии функции, а вызовет ее уже существующую копию.
3. Компилятор создает новую версию функции, только если тип переданного параметра не совпадает ни с одним из предыдущих вызовов.
Пример работы с шаблоном.
template <typename T> T Max (T A, T B) { return A > B ? A : B; } |
1. Шаблон генерирует множество функций, возвращающих большее из двух значений с одинаковым типом данных.
2. Оба параметра определены как параметры типа T и при вызове функции передаваемые переметры должны быть строго одного типа. В данном случае возможны такие вызовы функции:
cout << "Большее из 10 и 5 = " << Max(10, 5) << "\n"; cout << "Большее из 'A' и 'B' = " << Max('A', 'B') << "\n"; cout << "Большее из 3.5 и 5.1 = " << Max(3.5, 5.1) << "\n"; |
А такой вызов приведет к ошибке:
cout << "Большее из 10 и 5.55 = " << Max(10, 5.55); // ОШИБКА! |
Компилятор не сможет преобразовать параметр int в double.
Решением проблемы передачи разных параметров является такой шаблон:
template <typename T1, typename T2> T2 Max(T1 A , T2 B) { return A > B ? A : B; }
|
В этом случае Т1 обозначает тип значения, передаваемого в качестве первого параметра, а Т2 - второго.
Внимание!!!
Каждый параметр типа, встречающийся внутри угловых скобок, должен ОБЯЗАТЕЛЬНО появляться в списке параметров функции. В противном случае произойдет ошибка на этапе компиляции.(Естественно, только в том случае, если функция будет вызвана.)
template <typename T1, typename T2> T1 Max(T1 A , T1 B) { return A > B ? A : B; } // ОШИБКА! список параметров должен включать T2 как параметр типа. |
Переопределение шаблонов функций
1. Каждая версия функции, генерируемая с помощью шаблона, содержит один и тот же фрагмент кода.
2. Однако, для отдельных параметров типа можно обеспечить особую реализацию кода, т. е. определить обычную функцию с тем же именем, что и шаблон.
3. Обычная функция переопределит шаблон. Если компилятор находит типы переданных параметров соответствующие спецификации обычной функции, то он вызовает ее, и не создает функцию по шаблону
