Подобно последовательным контейнерам (см. раздел 9.2.2), для доступа к члену класса, например типа map::key_type, используется оператор области видимости.

Тип mapped_type определен только для типов карт (unordered_map, unordered_multimap, multimap и map).

<p>11.3.1. Итераторы ассоциативных контейнеров</p>

При обращении к значению итератора возвращается ссылка на значение типа value_type контейнера. В случае карты типом value_type является пара, переменная-член first которой содержит константный ключ, а переменная-член second — значение:

// получить итератор на элемент контейнера word_count

auto map_it = word_count.begin();

// *map_it - ссылка на объект типа pair

cout << map_it->first;         // отобразить ключ элемента

cout << " " << map_it->second; // отобразить значение элемента

map_it->first = "new key";     // ошибка: ключ является константой

++map_it->second; // ok: значение можно изменить, используя итератор

Не следует забывать, что типом value_type карты является pair и что можно изменять ее значение, но не ключ.

Итераторы наборов константны

Хотя типы наборов определяют типы iterator и const_iterator, оба типа итераторов предоставляют доступ к элементам в наборе только для чтения. Подобно тому, как нельзя изменить ключевую часть элемента карты, ключи в наборе также константны. Итератор набора можно использовать только для чтения, но не для записи значения элемента:

set iset = {0,1,2,3,4,5,6,7,8,9};

set::iterator set_it = iset.begin();

if (set_it != iset.end()) {

 *set_it = 42;            // ошибка: ключи набора только для чтения

 cout << *set_it << endl; // ok: позволяет читать ключ

}

Перебор ассоциативного контейнера

Типы map и set поддерживают все функции begin() и end() из табл. 9.2. Как обычно, эти функции можно использовать для получения итераторов, позволяющих перебрать контейнер. Например, цикл вывода результатов программы подсчета слов из раздела 11.1 можно переписать следующим образом:

// получить итератор на первый элемент

auto map_it = word_count.cbegin();

// сравнить текущий итератор с итератором после конца

while (map_it != word_count.cend()) {

 // обратиться к значению итератора, чтобы отобразить

 // пару ключ-значение элемента

 cout << map_it->first << " occurs "

      << map_it->second << " times" << endl;

 ++map_it; // прирастить итератор, чтобы перейти на следующий элемент

}

Условие цикла while и инкремент итератора в теле цикла такие же как в программах вывода содержимого векторов или строк. Итератор map_it инициализирован позицией первого элемента контейнера word_count. Пока итератор не равен значению, возвращенному функцией end(), возвращается текущий элемент, а затем происходит приращение итератора. Оператор вывода обращается к значению итератора map_it для получения членов пары, оставаясь в остальном тем же, что и в первоначальной программе.

Вывод этой программы имеет алфавитный порядок. При использовании итераторов для перебора контейнеров map, multimap, set и multiset они возвращают элементы в порядке возрастания ключа.

Ассоциативные контейнеры и алгоритмы

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

Перейти на страницу:

Похожие книги