|
Программирование >> Инициализация объектов класса, структура
size определяет размер параметра-массива и инициализирует / / переменно типа const int template <class Type, int size> Type min( const Type (&r array)[size] ) const int loc size = size; Type loc array[loc size]; Type loc array[loc size]; Если в глобальной области видимости объявлен объект, функция или тип с тем же именем, что у параметра шаблона, то глобальное имя оказывается скрытым. В следующем примере тип переменной tmp не double, а тот, что у параметра шаблона typedef double Type; template <class Type> Type min( Type a, Type b ) tmp имеет тот же тип, что параметр шаблона Type, а не заданн глобальн typedef Type tm = a < b ? a : b; return tmp; Type: Объект или тип, объявленные внутри определения шаблона функции, не могут иметь то template <class Type> Type min( Type a, Type b ) ошибка: повторное объявление имени Type, совпадающего с именем параметра шаблона typedef double Type; Type tmp = a < b ? a : b; return tmp; же имя, что и какой-то из параметров: Имя параметра-типа шаблона можно использовать для задания типа возвращаемого правильно: T1 представляет тип значения, возвращаемого min(), а T2 и T3 - параметры-тип1 этой функции template <class T1, class T2, class T3> значения: T1 min( T2, T3 ); В одном списке параметров некоторое имя разрешается употреблять только один раз. Например, следующее определение будет помечено как ошибка компиляции: ошибка: неправильное повторное использование имени параметра Type template <class Type, class Type> Type min( Type, Type ); Однако одно и то же имя можно многократно применять внутри объявления или правильно: повторное использование имени Type внутри шаблона template <class Type> определения шаблона: i template <class Type> Type min( Type, Type ); Type max( Type, Type ); Имена параметров в объявлении и определении не обязаны совпадать. Так, все три все три объявления min() относятся к одному и тому же шаблону функции опережающие объявления шаблона template <class T> T min( T, T ); template <class U> U min( U, U ); фактическое определение шаблона template <class Type> объявления min() относятся к одному и тому же шаблону функции: Type min( Type a, Type b ) { /* ... */ } Количество появлений одного и того же параметра шаблона в списке параметров функции не ограничено. В следующем примере Type используется для представления #include <vector> правильно: Type используется неоднократно в списке параметров шаблона template <class Type> двух разных параметров: Type sum( const vector<Type> &, Type ); Если шаблон функции имеет несколько параметров-типов, то каждому из них должно правильно: ключевые слова typename и class могут перемежаться template <typename T, class U> T minus( T*, U ); ошибка: должно быть <typename T, class U> или <typename T, typename U> template <typename T, U> предшествовать ключевое слово class или typename: T sum( T*, U ); template <class Parm, class U> Parm minus( Parm* array, U value ) Parm::name * p; это объявление указателя или умножение? На самом деле умножение класса Parm? Компилятор не знает, является ли name типом, поскольку определение класса, представленного параметром Parm, недоступно до момента конкретизации шаблона. Чтобы такое определение шаблона можно было разобрать, пользователь должен подсказать компилятору, какие выражения включают типы. Для этого служит ключевое слово typename. Например, если мы хотим, чтобы выражение Parm::name в шаблоне функции minus() было именем типа и, следовательно, вся строка трактовалась как template <class Parm, class U> Parm minus( Parm* array, U v minus( Parm* array, U value ) typename Parm::name * p; теперь это объявление указателя объявление указателя, то нужно модифицировать текст следующим образом: Ключевое слово typename используется также в списке параметров шаблона для указания того, что параметр является типом. Шаблон функции можно объявлять как inline или extern - как и обычную функцию. Спецификатор помещается после списка параметров, а не перед словом template. В списке параметров шаблона функции ключевые слова typename и class имеют одинаковый смысл и, следовательно, взаимозаменяемы. Любое из них может использоваться для объявления разных параметров-типов шаблона в одном и том же списке (как было продемонстрировано на примере шаблона функции minus() ). Для обозначения параметра-типа более естественно, на первый взгляд, употреблять ключевое слово typename, а не class, ведь оно ясно указывает, что за ним следует имя типа. Однако это слово было добавлено в язык лишь недавно, как часть стандарта C++, поэтому в старых программах вы скорее всего встретите слово class. (Не говоря уже о том, что class короче, чем typename, а человек по природе своей ленив.) Ключевое слово typename упрощает разбор определений шаблонов. (Мы лишь кратко остановимся на том, зачем оно понадобилось. Желающим узнать об этом подробнее рекомендуем обратиться к книге Страуструпа Design and Evolution of C++ .) При таком разборе компилятор должен отличать выражения-типы от тех, которые таковыми не являются; выявить это не всегда возможно. Например, если компилятор встречает в определении шаблона выражение Parm::name и если Parm - это параметр-тип, представляющий класс, то следует ли считать, что name представляет член-тип
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |