Анимация
JavaScript
|
Главная Библионтека вать или сравнивать друг с другом (при отсутствии соответствующего преобразования типа). Параметры шаблонов по умолчанию Шаблоны классов могут иметь параметры по умолчанию. Например, следующий фрагмент разрешает объявлять объекты класса MyClass как с одним, так и с двумя аргументами: template <class Т. class container = vector<T> > class MyClass; При передаче одного аргумента вместо второго используется параметр по умолчанию: HyClass<int> х1; Эквивалентно MyClass<1nt.vector<1nt> > Аргументы шаблонов по умолчанию могут определяться на основе предыдущих аргументов. Ключевое слово typename Ключевое слово typename означает, что следующий за ним идентификатор обозначает тип. Рассмотрим следующий пример; template <class Т> class MyClass { typename Т:iSubType * ptr; В этом фрагменте ключевое слово typename поясняет, что SubType является подтипом класса Т, Следовательно, ptr - указатель на тип T::SubType. Без typename идентификатор SubType интерпретируется как статический член класса, а следующая строка воспринимается как умножение значения SubType типа Т на ptr: Т::SubType * ptr Поскольку идентификатор SubType объявлен типом, любой тип, используемый вместо Т, должен содержать внутренний тип SubType. Например, испо-льзо-вание типа Q в качестве аргумента шаблона, как показано ниже, возможно то./1ь-ко при условии, что в Q определяется внутренний тип SubType: HyClass<Q> х; Объявление выглядит примерно так: class Q { typedef 1nt SubType; * Обратите внимание на пробел между символами >. Последовательность > воспринимается компилятором как оператор сдвига, что приводит к синтаксической ошибке. В этом случае переменная ptr класса MyClass<Q> является указателем на тип int. Однако подтип также может быть абстрактным типом данных (например, классом): class Q { class Sublype: Ключевое слово typename всегда должно квалифицировать идентификатор шаблона как тип, даже если другая интерпретация не имеет смысла. В С++ любой идентификатор шаблона, указанный без ключевого слова typename, интерпретируется как значение. Ключевое слово typename также может использоваться вместо слова class в объявлении шаблона: template <typename Т> class MyClass: Шаблонные функции классов Допускается определение функций классов в виде шаблонов, С другой стороны, такие функции не могут быть виртуальными и не имеют параметров по умолчанию. Пример: class MyClass { template <class Т> void f(T): Шаблон MyClass:f объявляет набор функций с параметром произвольного типа. При вызове функции может передаваться любой аргумент (при условии, что его тип поддерживает все операции, используемые в f). Данная возможность часто используется для автоматического преобразования типов в классах шаблонов. Например, в следующем определении аргумент х функции assignO должен точно соответствовать типу объекта, для которого он вызывается: template <class Т> class MyClass { private: Т value; public; void assign ( const MyClass<T>& x) { Тип x должен соответствовать типу *th1s value = x.value; Однако использование шаблона с другим типом при вызове assign() является ошибкой даже в том случае, если между типами выполняется автоматическое преобразование: void fO { MyClass<double> d: MyClass<int> 1: d.assign(d): OK d.assign(i): ОШИБКА: i относится к типу MyClass<int>. но в данном случае ОБЯЗАТЕЛЕН тип MyClass<double> Определение другого шаблона для функции позволяет обойти требование точного совпадения типов. В этом случае аргумент может иметь произвольный тип шаблона (при условии, что типы совместимы по присваиванию): template <class Т> class MyClass { private: Т value; public: template <class X> Шаблон функции позволяет void assign (const MyClass<X>& x) { использовать другие типы value = x,getValue(): шаблонов при присваивании. Т getValue О const { return value: void fO { MyCla5S<double> d; MyClass<1nt> 1; d.ass1gn(d); OK d.assignd); OK (тип int совместим с double no присваиванию) Поскольку тип аргумента х функции assign теперь отличен от *this, прямой доступ к закрытым и защищенным членам MyClasso невозможен. Вместо этого приходится использовать обходные пути вроде функции getValue() из рассмотренного примера. Шаблонный конспхруктор представляет собой особую разновидность шаблона, определяемую внутри класса. Шаблонные конструкторы обычно определяются для обеспечения неявных преобразований типов при копировании объектов. Учтите, что шаблонный конструктор ие замещает стандартный копирующий конструктор. При точном соответствии типов будет сгенерирован и вызван стандартный копирующий конструктор. Пример: template <class Т> class MyClass { publ ic: Шаблонный конструктор с автоматическим преобразованием типа 0 1 2 [ 3 ] 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |