Таким образом, шаблоны нельзя «просто делить» на части и транслировать раздельно. Шаблон представляет собой только заготовку для построения кода: пока шаблон не инстанцирован, объектного кода из него не получится, и компоновщику нечего будет собирать. Модули, использующие шаблон, с помощью директивы #include должны подключить файл с полным определением шаблона. Это касается и шаблонов классовой шаблонов функций. Такой способ организации кода с шаблонами называется «моделью включения» [28]. Его главный недостаток нам уже хорошо известен — необходимость трансляции сразу всей программы.
Явное инстанцирование
Стандарт С++ предлагает еще один вариант организации кодов с шаблонами — модель явного инстанцирования (см. п. п. 14.7.2 в [1]). При такой организации шаблон инстанцируется вручную с помощью директивы явного инстанцирования. Рассмотрим наш пример с шаблоном функции Summa (). Создадим в проекте три модуля:
1. Модуль с шаблоном функции (см. листинг 12.1).
2. Модуль с функцией main(), в котором задан прототип шаблона (см. листинг 13.12).
3. Модуль с набором директив явного инстанцирования Summalnst.h (листинг 13.13).
Листинг 13.13. Файл с директивами явного инстанцирования
// - -файл-Summa Inst. h
#include <string> using namespace std;
#include "Summa.h" // подключение шаблона
// набор директив явного инстанцирования
template double Summa<double>(double const *begin, double const *end); template int Summa<int>(int const *begin, int const *end); template short Summa<short>(short const "begin, short const *end); template string Summa<string>(string const *begin, string const *end);
Директива явного инстанцирования должна начинаться с ключевого слова template; за ним следует объявление объекта, экземпляр которого со всеми выполненными подстановками надо генерировать. В нашем примере (см. листинг 13.12) в функции mai п () четыре вызова функции Summa (). Поэтому в файле с директивами инстанцирования у нас четыре директивы с аргументами как раз тех типов, которые используются во время вызовов функции Summa().
Обратите внимание, что в модуле с функцией main О (см. листинг 13.12) мы не подключаем ни шаблон, ни файл с директивами явного инстанцирования. Нам в этом модуле необходим только прототип шаблона. Тем не менее все транслируется, собирается и выполняется правильно.
Можно сочетать модель явного инстанцирования и модель включения. Например, можно подключить файл явного цнстанцирования Summalnst.h в модуле main.cpp:
#include "Summalnst.h"
Для программистов часто бывает нужно создать сеть. Все для создания сети можно найти в магазине - сетевуха - http://setevuha.com.ua/servernoe_servery/. На этом сайты вы обязательно подберете сервер под ваши нужды.
Естественно, прототип функции-шаблона в этом случае можно убрать.
Теперь рассмотрим модель явного инстанцирования для классов. Включим в проект следующие модули:
• файл TStack.h с определением интерфейса класса-шаблона TStack (см. листинг 13.10);
• файл TStackdef.h с реализацией методов класса-шаблона TStack (см. листинг 13.10);
• файл main.cpp с главной функцией (см. листинг 13.11);
• файл TStacklnst.cpp с директивами явного инстанцирования (листинг 13.14). |