Программирование >>  Инициализация объектов класса, структура 

1 ... 160 161 162 [ 163 ] 164 165 166 ... 395


template <typename Type>

Type sum( Type op1, Type op2 ) { /* ... */ }

явное объявление конкретизации

sum(int*, int) :

template int* sum< int* >( int*, int );

Здесь в качестве аргумента явно задается int*. Явное объявление конкретизации с одним и тем же множеством аргументов шаблона может встречаться в программе не более одного раза.

Определение шаблона функции должно находиться в том же файле, где и явное объявление конкретизации. Если же его не видно, то явное объявление приводит к ошибке:

компиляторы поддерживают такую модель, а те, которые поддерживают, не всегда делают это правильно: модель с разделением требует более изощренной среды программирования, которая доступна не во всех реализациях C++. (В другой нашей книге, Inside C++ Object Model , описан механизм конкретизации шаблонов, поддержанный в одной из реализаций C++, а именно в компиляторе Edison Design Group.)

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

10.5.3. Явные объявления конкретизации

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

Результат работы программы не зависит от того, сколько раз конкретизировался шаблон: в конечном итоге используется лишь один экземпляр. Но если приложение состоит из большого числа файлов, то время компиляции приложения заметно возрастает.

Подобные проблемы, характерные для старых компиляторов, затрудняли использование шаблонов. Поэтому в стандарте C++ введено понятие явного объявления конкретизации, помогающее программисту управлять моментом, когда конкретизация происходит.

В явном объявлении конкретизации за ключевым словом template идет объявление шаблона функции, в котором его аргументы указаны явно. Рассмотрим шаблон



#include <vector>

template <typename Type>

Type sum( Type op1, int op2 ); только объявление

определяем typedef для vector< int > typedef vector< int > VI;

ошибка: sum() не определен

template VI sum< VI >( VI , int );

Если в некотором исходном файле встречается явное объявление конкретизации, то что произойдет в других файлах, где используется такая же конкретизация шаблона функции? Как сказать компилятору, что явное объявление находится в другом файле и что при использовании в этом файле шаблон конкретизировать не надо?

Явные объявления конкретизации используются в сочетании с опцией компилятора, которая подавляет неявную конкретизацию шаблонов. Название опции в разных компиляторах различно. Например, в VisualAge for C++ для Windows версии 3.5 фирм: IBM эта опция называется /ft-. Если приложение компилируется с данной опцией, то компилятор предполагает, что шаблоны будут конкретизироваться явно, и не выполняет автоматической конкретизации.

Разумеется, если мы не включили в программу явного объявления конкретизации для некоторого шаблона, но задали опцию /ft-, то при сборке произойдет ошибка из-за того, что функция не была конкретизирована.

Упражнение 10.8

Назовите две модели компиляции шаблонов, поддерживаемые в C++. Объясните, как организуются определения шаблонов функций в каждой модели.

Упражнение 10.9

template <typename Type>

Пусть дано следующее определение шаблона функции sum() :

Type sum( Type op1, char op2 );

Как записать явное объявление конкретизации этого шаблона с аргументом типа

string?

10.6. Явная специализация шаблона А

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



обобщенное определение шаблона template <class T>

T max( T t1, T t2 ) {

return ( t1 > t2 ? t1 : t2 );

Когда этот шаблон конкретизируется с аргументом типа const char*, то обобщенное определение оказывается семантически некорректным, если мы интерпретируем каждый аргумент как строку символов в смысле языка C, а не как указатель на символ. В этом случае необходимо предоставить специализированное определение для конкретизации шаблона.

Явное определение специализации - это такое определение, в котором за ключевым словом template следует пара угловых скобок <>, а за ними - определение специализированного шаблона. Здесь указывается имя шаблона, аргументы, для которых он специализируется, список параметров функции и ее тело. В следующем примере для

#include <cstring>

явная специализация для const char*: имеет приоритет над конкретизацией шаблона по обобщенному определению

typedef const char *PCC;

template<> PCC max< PCC >( PCC s1, PCC s2 ) {

max(const char*, const char*) определена явная специализация:

return ( strcmp( s1, s2 ) > 0 ? s1 : s2 );

Поскольку имеется явная специализация, шаблон не будет конкретизирован с типом const char* при вызове в программе функции max(const char*, const char*) . При любом обращении к max() с двумя аргументами типа const char* работает специализированное определение. Для любых других обращений функция сначала конкретизируется по обобщенному определению шаблона, а затем вызывается. Вот как

#include <iostream>

быть определение шаблона функции max() изации для аргументов const char*

здесь должно

и его специализации для аргументов const char* int main() {

вызов конкретизированной функции: int max< int >( int, int ); int i = max( 10, 5 ) ;

const char* max< const char* >( const char*, const char* ); const char *p = max( hello , world );

cout << i: << i << p: << p << endl; return 0;

это выглядит:



1 ... 160 161 162 [ 163 ] 164 165 166 ... 395

© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика