Программирование >>  Операторы преобразования типа 

1 ... 60 61 62 [ 63 ] 64 65 66 ... 239


find() возвращает end(). Функция find() не может использоваться для поиска элемента с заданным значением. Вместо этого приходится задействовать универсальный алгоритм типа find if() или программировать цикл. Ниже приведен пример простого цикла, выполняющего некоторую операцию для каждого элемента с заданным значением:

std::mu]timap<std::string.float> coll:

Выполнение операции над всеми элементами с заданным значением std: :rnult1rnap<std::string.float>::iterator pos: for (pos *= coll .beginO: pos != coll.endO: ++pos) { 1f (pos->second == value) { do someth1ng();

Если цикл используется для удаления элементов, будьте осторожны - но ошибке можно отпилить ветку, на которой сидишь . За подробностями обращайтесь на с. 211.

Искать элемент с заданным значением при помощи алгоритма find if() еще сложнее, чем запрограммировать цикл, поскольку для этого придется создать объект функции, сравнивающий значение элемента с заданным значением. Пример приведен на с. 217.

Функции lovifer bound(), upper bound() и equaLrange() работают так же, как во множествах (см. с. 188), за исключением того, что позиция определяется по ключу.

Присваивание

в отображениях и мультиотображениях определены только базовые операции присваивания, поддерживаемые всеми контейнерами (табл, 6.29). Дополнительная информация приведена на с. 156.

Таблица 6.29. Операции присваивания для отображений и мультиотображений Операция Описание

с1 = с2 Присваивает с1 все элементы с2

cl.swap(c2) Меняет местами содержимое с1 и с2

swap(cl,c2) То же, но в форме глобальной функции

Для выполнения операций присваивания контейнеры должны относиться к одному типу. В частности, должны совпадать типы критериев сравнения, хотя сами критерии могут различаться. Пример использования разных критериев сортировки, относящихся к одному тину, приведен на с. 198. Если критерии различаются, в результате присваивания или перестановки они также меняются местами.

Функции получения итераторов

Отображения и мультиотображения не поддерживают прямой доступ к элементам, поэтому для обращения к элементам обычно используются итераторы.



Впрочем, у этого правила существует исключение: отображения поддерживают оператор индексирования [] для прямого обращения к элементам (см. с. 212). В табл. 6.30 перечислены стандартные функции получения итераторов, поддерживаемые отображениями и мультиотображениями.

Таблица 6.30. Операции получения итераторов для отображений и мультиотображений Операция Описание

C.beginO Возвращает двунаправленный итератор для первого элемента

(ключи считаются константными)

C.endO Возвращает двунаправленный итератор для позиции за последним

элементом (ключи считаются константными)

c.rbeginO Возвращает обратный итератор для первого элемента при переборе

а обратном направлении

C.rendO Возвращает обратный итератор для позиции за последним элементом

при переборе в обратном напраалении

Итераторы отображений и мультиотображений, как и во всех классах ассоциативных контейнеров, являются двунаправленными (см. с. 261). Такие итераторы не могут использоваться алгоритмами, рассчитанными на итераторы произвольного доступа (например, алгоритмами сортировки или случайной перестановки элементов).

Но еще более важное ограничение заключается в том, что с точки зрения итератора все ключи элементов отображения или мультиотображения считаются константными (то есть элемент интерпретируется как относящийся к типу pair<const кеу,Т>). Это необходимо для того, чтобы программа не могла нарушеть упорядоченность элементов, изменяя их ключи. Однако в результате для элементов отображения или мультиотображения вызов модифицирующих алгоритмов становится невозможным. Например, удаление элементов не может осуществляться алгоритмом remove(), потому что удаление в действительности сводится к перезаписи следующими элементами (данная тема подробно обсуждается на с. 125). Элементы множеств и мультимножеств удаляются только функциями, предоставляемыми контейнером.

Пример использования итераторов:

std::map<std::string.f1oat> col 1:

std: :rnap<std: :string.float>::iterator pos: for (pos = coll.beginO: pos != coll.endO: ++pos) ( std;:cout key: pos->first \t

value: pos->second std::endl:

Итератор pos используется для перебора в последовательности пар string/float. Выражение pos->first определяет ключ элемента, а выражение pos->second - значение элемента.

pos->first является сокращенной записью для (*po.s).first. Некоторые старые библиотеки поддерживают только полную форму записи.



typename Cont::iterator pos;

pos = c.find(old key):

1f (pos [= C.endO) {

Вставка нового элемента со значением старого элемента c.insert(typename Cont;:value type(new key.

pos->second));

Удаление старого элемента c,erase(pos); return true:

else {

Ключ не найден return false:

Функции insertO и erase() описаны в следующем подразделе. При вызове этой унифггцированной функции контейнеру просто передаются два ключа; старый и новый. Пример:

std:;map<std::String.float> coll;

MyLib::гер1асе кеу(со11, old key , new key );

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

Вставка нового элемента со значением старого элемента coll[ new key ] = coll[ old key ];

Попытка изменения ключа приводит к ошибке:

pos->f1rst = hello : ОШИБКА компипяции

Однако модификация значения элемента выполняется без проблем (при условии, что зпачение не принадлежит к константному типу):

po5>second = 13.5; OK

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

cont/newkey.hpp namespace MyLib {

template <class Cont>

inline

bool replace key (Cont& c.

const typename Cont;:key type& old key. const typename Cont;;key type& newkey)



1 ... 60 61 62 [ 63 ] 64 65 66 ... 239

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