Анимация
JavaScript


Главная  Библионтека 

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

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

О Использование типа pair<>. Другой способ основан на непосредственном использовании типа pair. Пример:

std::rnap<std:: string. f 1 oat> col 1; С неявным преобразованием

coll.insert сstd:;pa1r<std::string.float>("otto".22.3)); С явным преобразованием

coll-insert(std::pair<const std::String.float>("otto".22.3)):

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

О Использование функции makejpairQ. Вероятно, самый удобный способ основан на использовании функции nriake pair() (см. с. 53). Функция создает объект pair из двух компонентов, переданных в аргументах:

std::map<std::strlng.float> coll:

coll .1nsert(std: :rnake pa1 r("otto".22.3)):

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

В следующем простом примере вставки элемента в отображение мы также проверяем, успешно ли завершилась операция:

std::map<std::string.float> coll:

if (coll.insert(std::make pair("otto".22,3)).second) {

std::cout « "OK. could insert otto/22.3" « std::endl:

else {

std::cout « "Oops, could not insert otto/22.3 "

« "(key otto already exists" « std:;endl:

Возвращаемые значения функции insert() описаны на с. 191; там же приведены примеры использования этой функции, применимые и к отображениям. Стоит снова напомнить, что в отображениях предусмотрен более удобньп"! способ вставки (и присваивания) элементов с помощью оператора индексирования (см. с. 212).

Чтобы удалить элемент с известным ключом, достаточно вызвать функцию erase();

std:: rnap<std:: stri ng. f 1 oat> col 1:

Удаление всех элементов с заданным ключом coll.erase(key):



Эта версия erase() возвращает количество удаленных элементов. Для отображений возвращается либо О, либо 1.

Если мультиотображение содержит дубликаты, вам не удастся использовать функцию eraseO Для удаления только первого дубликата. Вместо этого можно воспользоваться следующим фрагментом:

typedef std: :mLilt1rnap<5td; :5tring,float> StringFloatMMap: StrlngFloatMMap coll;

Удаление первого элемента с переданным ключом StringFloatMMap::1terator pos; pos = col 1.find(key): 1f (pos != coll.endO) { coll.erase(pos):

Вместо алгоритма find() используется функция класса find(), нотому что она работает быстрее (см. пример на с. 163). Функция find() не годится для удаления элементов по известному значению (вместо ключа). Эта тема подробно обсуждается на с. 205.

При удалении элементов необходима осторожность, иначе вы рискуете «отпилить ветку, на которой сидите», то есть удалить элемент, на который ссылается итератор. Пример:

typedef std;:multirnap<std::string,float> StringFloatMap; StringFloatMap coll: StringFloatMap:;iterator pos:

for (pos = coll.beginO: pos != coll.endO; ++pos) { if (pos->second == value) {

coll.erase(pos); ОШИБКА ВРЕМЕНИ ВЫПОЛНЕНИЯ!!!

После вызова erase() для элемента, на который ссылается итератор pos, итератор становится недействительным. Любые попытки использования pos после удаления элемента без повторной инициализации - даже команда ++pos - приводят к непредсказуемым последствиям.

Если бы функция eraseO всегда возвращала значение следующего элемента, проблема решалась бы просто:

typedef std::multimap<std:;string.float> StringFloatMap: StringFloatMap coll; StringFloatMap::iterator pos:

for (pos = coll.beginO: pos != coll.endO: ) { if (pos->second == value) {



pos = coll.eraseCpos): Хорошо бы. но...

} происходит ОШИБКА КОМПИЛЯЦИИ!

else {

++pos:

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

Правильный способ удаления элемента, на который ссылается итератор, выглядит так:

typedef std::[nultimap<std::string.float> StringFloatMap; StringFloatMap coll: StringFloatMap::iterator pos;

Удаление всех элементов с заданным значением for (pos = coll.beginO: pos != coll.endO: ) { if Cpos->second == value) { coll .erase(pos++):

else { ++pos:

Постфиксная команда pos+-i- переводит итератор pos к следующему элементу, но возвращает копию исходного значения. Следовательно, в момент вызова erase() итератор pos не ссылается на удаляемый элемент.

Отображения как ассоциативные массивы

Ассоциативные контейнеры обычно ие предоставляют прямого доступа к своим элементам; все обращения к элементам производятся через итераторы. Впрочем, отображения являются исключением из этого правила. Неконстантные отображения поддерживают оператор индексирования [] для прямого доступа к элементам (табл. 6.32). Тем не менее в качестве «индекса» используется не целочисленная позиция элемента, а ключ, предназначенный для его идентификации. Это означает, что индекс может относиться к произвольному типу. Подобный интерфейс характерен для так называемых ассоциативных массивов.

Таблица 6.32. Прямой доступ к элементам отображения оператором [] Операция Описание

т[кеу] Возвращает ссылку на значение элемента с ключом key. Вставляет

элемент с ключом key, если его не существует



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