Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP.doc
Скачиваний:
7
Добавлен:
25.04.2019
Размер:
1.34 Mб
Скачать

Class MyTemplate

{ /* ... */ };

...

MyTemplate<short,unsigned,CAnotherClass,11> v;

// инстанцируется класс MyTemplate<short,unsigned,CAnotherClass<U>,unsigned=11>

...

MyTemplate<short,unsigned,CAnotherClass> vv;

// инстанцируется класс MyTemplate<short,unsigned,CAnotherClass<U>,unsigned=0>

...

MyTemplate<short,int> vvv;

// инстанцируется класс MyTemplate<short,int,CSomeClass<T>,int=0>

...

MyTemplate<unsigned> vvvv;

// инстанцируется класс MyTemplate<unsigned,unsigned,CSomeClass<T>,unsigned=0>

...

MyTemplate<> vvvvv;

// инстанцируется класс MyTemplate<int,int,CSomeClass<T>,int=0>

Каждому виду параметров шаблона соответствует свой набор аргументов (это, в частности, уже должно быть ясно из приведенного примера и всего изложения). Аргументы тоже делятся на аргументы-типы, шаблонные аргументы и ординарные аргументы.

Аргумент-тип представляет собой идентификатор стандартного или определенного пользователем типа. Этот тип не может быть локальным. Он должен иметь какой-либо из типов компоновки. Наконец, он должен иметь имя.

Шаблонный аргумент – это имя ранее определенного шаблонного класса. Специализации шаблонов в качестве таких аргументов не допускаются.

Ординарный аргумент – это имя или выражение, подставляемое вместо ординарного параметра.

Ординарный параметр может иметь интегральный или перечислимый тип (возможно, с модификаторами), быть ссылкой или указателем на объект или функцию, а также быть указателем на компонент. Если ординарный параметр не является ссылкой, то он представляет собой праводопустимое выражение (соответственно, нельзя получить его адрес, ему нельзя присвоить значение и т.д.). Ординарный параметр не может иметь тип void, он также не может быть вещественным (но может быть указателем или ссылкой на вещественный тип) и не может быть классом.

Ординарный аргумент может представлять собой константное выражение интегрального или перечислимого типа, имя ординарного параметра, имя объекта или функции с внешним типом компоновки (включая шаблоны функций), адрес объекта, функции или шаблона функций с внешним типом компоновки, а также указатель на компонент. Он не может быть ни строковым литералом, ни адресом элемента массива, ни адресом или именем нестатического компонента класса. Также недопустимым ординарным аргументом будет леводопустимое выражение без внешней компоновки. При необходимости выполняются автоматические преобразования типов ординарных аргументов (например, расширение интегральных типов22, преобразование вида «массив–указатель» и др.).

Ниже приводится пример, иллюстрирующий использование различных аргументов шаблонов и перечисленные ограничения.

Пример

template <const int & cnref> struct Template1 { /* ... */ };

...

Template1<100> object1; // ошибка, привязка ссылки к временному объекту

int nvar = 100;

Template1<nvar> object2; // нормально

...

template <int * pn> class Template2 { /* ... */ };

Int array[10]; struct Structure { int m; static int sm; } str;

...

Template2<&array[0]> object3; // ошибка, адрес элемента массива

Template2<&str.m> object4; // ошибка, адрес нестатического компонента

Template2<&Structure::sm> object5; // нормально, адрес статического компонента

...

template <class T, char * psz> class Template3 { /* ... */ };

...

Template3<int,”token”> object6; // ошибка, строковый литерал

char psz[] = “another token”;

Template3<int,psz> object7; // нормально

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]