Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Козин С. В. ООП. Лекции.doc
Скачиваний:
57
Добавлен:
06.07.2020
Размер:
489.47 Кб
Скачать

Инстанцирование шаблона функции

Инстанцирование шаблона функции состоит в построении определения конкретной функции. Различают явное и неявное инстанцирование шаблона функции. Наиболее часто используется неявное инстанцирование шаблона функции.

Неявное инстанцирование

Неявное инстанцирование выполняется на основе анализа компилятором вызова функции. Компилятор анализирует типы аргументов вызова функции. На основе этого анализа определяются аргументы шаблона. Вообще говоря, этот процесс не всегда завершается успехом. Такие случаи будут рассмотрены. Однако, если такой процесс оказался успешным, то аргументы шаблона в его определении заменят параметры шаблона и компилятор построит определение конкретной функции. Отметим, что инстанцирование выполнять не будет (в нем нет необходимости) в том случае, когда определение конкретной функции уже было ранее построено.

Пример. Инстанцирование шаблона функции для определения максимального значения двух величин

#include <iostream> using std :: cout; using std :: endl; template <typename T> T Max(T a, Tb); int main() { int i = 2; int j = 3; cout << Max(i, j) << endl; double d1 = 1.0; double d2 = 5.0; cout << Max(d1, d2) << endl; double d3 = 4.0; double d4 = 8.0; cout << Max(d3, d4) << endl; // cout << Max(i, d3) << endl; return 0; } template <typename T> T Max(T a, Tb) { return (a > b) ? a : b; }

В приведенном выше программном коде шаблон функции Max инстанцируется дважды:

  • Для вызова Max(i, j)/

  • Для вызова Max(d1, d2)

Необходимость в инстанцировании шаблона при компиляции вызова Max(d3, d4).отсутствует. При попытке компиляции вызова Max(i, d3) появляется сообщение об ошибке (error):

Could not find a match for Max<>(int, double)

При компиляции первого вызова (Max(I, j)) компилятор устанавливает, что в шаблоне функции необходимо сделать подстановку T == int. Аналогично при компиляции второго вызова (Max(d1, d2)) компилятор выявит необходимость в подстановке T == double.

При компиляции четвертого вызова (Max(I, d3)) возникает противоречие, состоящее в следующем. Если исходить из первого аргумента вызова функции (i), то необходимо выполнять подстановку T == int. В то же время, исходя из второго параметра вызова (d3), необходимо выполнить другую подстановку: T == double. Возникающий конфликт компилятор разрешить не может. Заменим, что автоматические преобразования типов при инстанцировании шаблона не допускаются.

В последних версиях компилятора рассматриваемая трудность может быть преодолена с помощью явного аргумента шаблона. Для этого вызов Max2(i, d3) следует заменить вызовом Max<double>(I, d3). Это позволит выполнить программу со снятым комментарием

Явное инстанцирование конкретной функции

Эта разновидность инстанцирования выполняется с помощью директивы явного инстанцирования. Директива явного инстанцирования начинается зарезервированным словом template. За этим словом должно следовать объявление той специализации, которую необходимо сгенерировать. Например, при использовании директивы явного инстанцирования :

template void Swap<double>(double&, double&);

будет сгенерировано определение конкретной функции из семейства Swap, для которой T == double.

Директива явного инстанцирования создает так называемую точку явного инстанцирования POI (point of instantiation). POI – это позиция в исходном коде, в которой шаблон мысленно разворачивается путем подстановки аргументов шаблона вместо параметров.