- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Язык программирования C++. Пятое издание - Стенли Липпман
Шрифт:
Интервал:
Закладка:
11.3.1. Итераторы ассоциативных контейнеров
При обращении к значению итератора возвращается ссылка на значение типа value_type контейнера. В случае карты типом value_type является пара, переменная-член first которой содержит константный ключ, а переменная-член second — значение:
// получить итератор на элемент контейнера word_count
auto map_it = word_count.begin();
// *map_it - ссылка на объект типа pair<const string, size_t>
cout << map_it->first; // отобразить ключ элемента
cout << " " << map_it->second; // отобразить значение элемента
map_it->first = "new key"; // ошибка: ключ является константой
++map_it->second; // ok: значение можно изменить, используя итератор
Не следует забывать, что типом value_type карты является pair и что можно изменять ее значение, но не ключ.
Итераторы наборов константныХотя типы наборов определяют типы iterator и const_iterator, оба типа итераторов предоставляют доступ к элементам в наборе только для чтения. Подобно тому, как нельзя изменить ключевую часть элемента карты, ключи в наборе также константны. Итератор набора можно использовать только для чтения, но не для записи значения элемента:
set<int> iset = {0,1,2,3,4,5,6,7,8,9};
set<int>::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) не используются. Тот факт, что ключи константны, означает невозможность передачи итераторов ассоциативных контейнеров алгоритмам, которые пишут или переупорядочивают элементы контейнеров. Таким алгоритмам нужна возможность записи в элементы. Элементы всех типов наборов константны, а у всех типов карт константным является первый член пары.
Ассоциативные контейнеры применимы с теми алгоритмами, которые только читают элементы. Однако большинство этих алгоритмов осуществляет поиск в последовательности. Поскольку поиск элементов в ассоциативном контейнере осуществляется быстро (по ключу), как правило, не имеет смысла использовать для них обобщенный алгоритм поиска. Например, как будет продемонстрировано в разделе 11.3.5, ассоциативные контейнеры определяют функцию-член find(), позволяющую непосредственно выбрать элемент с заданным ключом. Для поиска элемента можно использовать обобщенный алгоритм find(), но он осуществляет последовательный поиск. Поэтому намного быстрее использовать функцию-член find() класса контейнера, чем вызывать обобщенную версию.
На практике, если это вообще происходит, ассоциативный контейнер используется с алгоритмами в качестве исходной последовательности или последовательности назначения. Например, обобщенный алгоритм copy() можно использовать для копирования элементов ассоциативного контейнера в другую последовательность. Точно так же адаптер inserter можно использовать для связи итератора вставки (см. раздел 10.4.1) с ассоциативным контейнером. Адаптер inserter позволяет использовать ассоциативный контейнер как место назначения для другого алгоритма.
Упражнения раздела 11.3.1Упражнение 11.15. Каковы типы mapped_type, key_type и value_type карты, переменные-члены пар которой имеют типы int и vector<int>?
Упражнение 11.16. Используя итератор карты, напишите выражение, присваивающее значение элементу.
Упражнение 11.17. С учетом того, что с — контейнер multiset строк, a v — вектор строк, объясните следующие вызовы. Укажите, допустим ли каждый из них:
copy(v.begin(), v.end(), inserter(с, c.end()));
copy(v.begin(), v.end(), back inserter(c));
copy(c.begin(), c.end(), inserter(v, v.end()));
copy(c.begin(), c.end(), back inserter(v));
Упражнение 11.18. Перепишите определение типа map_it из цикла в данном разделы, не используя ключевое слово auto или decltype.
Упражнение 11.19. Определите переменную, инициализированную вызовом функции begin() контейнера multiset по имени bookstore из раздела 11.2.2. Определите тип переменной, не используя ключевое слово auto или decltype.
11.3.2. Добавление элементов
Функция-член insert() (табл. 11.4) добавляет один элемент или диапазон элементов в контейнер. Поскольку карта и набор (и их неупорядоченные версии) содержат уникальные ключи, попытка вставки уже присутствующего элемента не имеет никакого эффекта:
vector<int> ivec = {2,4,6,8,2,4,6,8}; // ivec содержит
// восемь элементов
set<int> set2; // пустой набор
set2.insert(ivec.cbegin(), ivec.cend()); // set2 имеет четыре элемента
set2.insert({1,3,5,7,1,3,5,7}); // теперь set2 имеет восемь элементов
Таблица 11.4. Функция insert() ассоциативного контейнера
с.insert(v) с.emplace(args) v — объект типа value_type; аргументы args используются при создании элемента. Элементы карты и набора вставляются (или создаются), только если элемента с данным ключом еще нет в контейнере с. Возвращает пару, содержащую итератор на элемент с заданным ключом и логическое значение, указывающее, был ли вставлен элемент. У контейнеров multimap и multiset осуществляется вставка (или создание) заданного элемента и возвращение итератора на новый элемент с.insert(b, e) с.insert(il) Итераторы b и е обозначают диапазон значений типа с::value_type; il — заключенный в скобки список таких значений. Возвращает void. У карты и набора вставляются элементы с ключами, которых еще нет в контейнере с. У контейнеров multimap и multiset вставляются все элементы диапазона c.insert(p, v) с.emplace(p, args) Подобны функциям insert(v) и emplace(args), но используют итератор p как подсказку для начала поиска места хранения нового элемента. Возвращает итератор на элемент с заданным ключомВерсии функции insert(), получающие пару итераторов или список инициализации, работают подобно соответствующим конструкторам (см. раздел 11.2.1), но добавляется только первый элемент с заданным ключом.
Добавление элементов в картуПри вставке в карту следует помнить, что типом элемента является pair. Зачастую объекта pair, подлежащего вставке, нет. В этом случае пара создается в списке аргументов функции insert():
// четыре способа добавления слова в word_count

