Явное создание представителя шаблона
В подавляющем большинстве случаев прикладному программисту нужно только сбросить флажок External в диалоге Project Options и больше не беспокоиться о том, как написанные им шаблоны классов будут обрабатываться. Однако, если вы хотите создать, например, динамическую библиотеку на основе шаблона, которая будет содержать код всех его функций-элементов, то для генерирования полного представителя шаблона вам придется воспользоваться директивой template.
Следующий пример включает в себя два исходных файла и один заголовочный, в котором определяется простой шаблон. Главный исходный модуль программы создает два шаблонных объекта для его аргументов int и float, но, поскольку модуль компилируется с директивой #pragma option -Jgx, то никакого кода для представителей шаблона в нем не создается. Вместо этого во втором исходном модуле (компилируемом с ключом -Jgx) явным образом генерируется полный представитель шаблона для аргумента float, а также неявно генерируется представитель для int, так как модуль ссылается на него.
Листинг 10.4. Директива порождения представителя шаблона
//////////////////////////////////////////////////
// Simptmpl.h: Простой шаблон класса.
//
template <class T> class Simple {
protected:
int size;
int current;
T *arr;
public:
Simple(int) ;
~Simple () ;
void Insert(T item)
{ if (current != size) arr[current++] = item; }
T SGet(int) ;
};
template <class T> inline Simple<T>::Simple(int n): size(n),
current (0), arr(new T[n]) {}
template <class T> Simple<T>::~Simple() { delete[] arr; }
template <class T> T SSimple<T>::Get(int idx) { return arr[idx]; }
void Somefunc(int);
/////////////////////////////////////////////////////////
// Instance.cpp: Порождение представителей шаблона. //
#pragma option -Jgx
#include <iostream.h>
#pragma hdrstop
#include <condefs.h>
#include "Simptmpl.h"
USEUNIT("Somefunc.cpp") ;
#pragma argsused
int main(int argc, char* argv[])
{
const int Num = 9;
Simple<int> ia(Num);
Simple<float> fa(Num);
fa.Insert(3.14) ;
cout << "Float In main(): " << fa.Get(O) << endl;
for (int i=0; i<Num; i++)
ia.Insert(i * 2);
cout << "From main(): ";
for (int i=0; i<Num; i++)
cout << ia.Get(i) << " ";
cout << end1;
Somefunc(10);
cin.ignore();
return 0;
}
//////////////////////////////////////////////////////////
// Somefunc.cpp: Функция, использующая шаблон класса. //
#pragma option -Jgd #include <iostream.h>
#pragma hdrstop #include "Simptmpl.h"
//
// Следующая строка генерирует явный представитель шаблона
// для типа float, хотя в данном модуле он не используется:
// template class Simple<float>;
void Somefunc(int n)
{
Simple<int> iArr(n);
for (int i=0; i<n; i++) iArr.Insert (i);
cout << "From Somefunc(): "<< n;
for (int i=0; i<n; i++)
cout<<" "<< iArr.Get(i);
cout <<end1; ;
}
Вывод программы показан на рис. 10.5.

Рис. 10.5 Результат работы программы Instance