Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

Метод

insert
предоставляет альтернативный метод добавления пар в отображение,
insert
выполняет строгую вставку, а не вставку/обновление, как
operator[]
. При использовании map (но не
multimap
, который может содержать дублирующиеся ключи)
insert
, если ключ уже существует, не делает ничего. По сравнению с ним
operator[]
, если ключ уже существует, заменяет значение объекта для этого ключа на новое.

Но синтаксис вставки требует несколько большей работы, чем

operator[]
, и он связан с тем, как
map
хранит данные. Рассмотрим строку из примера 6.6.

strMap.insert(std::make_pair("Sunday", "Sonntag"));

ma

p
хранит пары ключ/значение
в объекте
pair
,
pair
— это простой вспомогательный шаблон класса (объявленный в
<utility>
и включенный в
<map>
), который хранит два значения двух типов. Чтобы объявить
pair
из двух
string
, сделайте так.

pair<string, string> myPair;

Первый и второй элементы в

pair
доступны по открытым членам
first
и
second
. При использовании для доступа к элементам
map
оператора
operator[]
обычно работать с
pair
не приходится, но в случае со многими другими методами это придется делать, так что следует знать, как создавать и использовать объекты
pair
. Например, итераторы разыменовываются в простые объекты
pair
, так что при их использовании, как это делается в примере 6.6, следует знать, как получить ключ и его значение.

for (map<string, string> iterator p = strMap.begin;

 p != strMap.end; ++p)

 cout << "English: " << p->first

<< ", German: " << p->second << endl;

Ключ хранится в

first
, а значение хранится в
second
.

Однако это не объясняет, почему я использовал

make_pair
.
make_pair
— это вспомогательный шаблон функции, который создает объект
pair
на основе двух переданных в него аргументов. Некоторые предпочитают этот подход вызову конструктора
pair
, так как шаблон класса не может догадаться о типах своих аргументов, в то время как шаблон функции может. Таким образом, эти две строки кода функционально эквивалентны.

strMap.insert(std::make_pair("Sunday", "Sonntag"));

strMap.insert(std::pair<string, string>("Sunday", "Sonntag"));

map
не допускает наличия дублирующихся ключей. Если требуется разрешить дублирование ключей, следует использовать
multimap
, который является
map
, разрешающим наличие несколько одинаковых ключей. Его интерфейс идентичен
map
, но поведение методов в необходимых случаях отличается. В табл. 6.1 приведен перечень методов, которые есть в одном, но отсутствуют в другом, и пояснения различий в поведении общих методов, map и
multimap
содержат несколько
typedef
, которые описывают различные значения, хранящиеся в них. В табл. 6.1 они используются следующим образом:

key_type

Это тип ключа. В

string map,
объявленном как
map<string, MyClass*>
,
key_type
должен быть
string
.

mapped_type

Это тип значения, на которое отображается ключ. В

string map
, объявленном как
map<string, MyClass*>
,
mapped_type
должен быть
MyClass*
.

value_type

Это тип объекта, содержащего ключ и значение, которой, применительно к

map
и
multimap
, является
pair<const key_type, mapped_type>
.

Табл. 6.1. map и multimap

Метод map, multimap или оба Поведение
T& operator[] (const key_type& k)
map
Возвращает ссылку на объект значения, сохраненный с ключом
k
. Если
k
в map отсутствует, то он добавляется, а объект значения создается с помощью конструктора по умолчанию
iterator insert(const value_type& v) pair<iterator, bool> insert(const value_type& v)
Оба Первая версия вставляет
v
в
multimap
и возвращает итератор, который указывает на вставленную пару
pair
. Вторая версия вставляет
v
и
map
при условии, что в
map
еще не содержится ключа, равного
v
. Возвращаемая
pair
содержит итератор который указывает на вставленную
pair
, если произошла вставка, и
bool
, указывающий, была ли вставка успешной
iterator find(const key_type& k)
Оба Возвращает итератор или
const_iterator
, который указывает на
mapped_type
, соответствующий
k
. В
multimap
не гарантируется, что возвращаемый итератор будет указывать на первое значение, соответствующее
k
. Если ключа, равного k, нет, то возвращаемый итератор равен
end

Также табл 6.1 показывает разницу в поведении между

map
и
multimap
.

Если

operator[]
вам не подходит, т.е. другой способ найти ключ в
map
. Для этого можно использовать метод
find
.

map<string, string>::const_iterator p

 = strMap.find("Thursday");

if (p != strMap.end)

 cout << "Thursday = " << p->second << endl;

Но не забудьте, что при использовании

multimap
не гарантируется, что возвращаемый элемент будет первым элементом с ключом, равным искомому. Если нужен первый элемент, чей ключ не меньше определенного значения или не больше определенного значения, используйте
lower_bound
или
upper_bound
.
lower_bound
возвращает итератор, указывающий на первую пару ключ/значение, равную или большую, чем аргумент
key_type
. Другими словами, если ваш
map
содержит дни недели, как в примере 6.6, следующий код вернет итератор, который указывает на пару, содержащую
"Friday"
и
"Freitag"
.

p = strMap.lower_bound("Foo");

if (p != strMap.end)

 cout << p->first << " = " << p->second << endl;

Это происходит благодаря тому, что первый ключ больше или равен

"Foo"
.
upper_bound
работает аналогично, но с противоположным условием.

В начале этого обсуждения я упоминал, что элементы в map хранятся в отсортированном по ключам порядке, так что при переборе от

begin
до
end
каждый элемент будет «больше», чем предшествующий (а в
multimap
— больше или равен ему) Но при использовании более сложных ключей, чем
string
или числа, может потребоваться указать, как при вставке элементов в отображение следует сравнивать ключи.

По умолчанию ключи хранятся с помощью стандартного функтора

less
(объявленного в
<functional>
).
less
— это двоичная функция (принимает два аргумента одинакового типа), которая возвращает
bool
, указывающий на то, больше ли первый аргумент, чем второй, или нет. Другими словами,
less(a, b)
возвращает
a < b
. Если это не то, что вам требуется, создайте свой собственный функтор и объявите
map
с его помощью. Например, если в качестве ключа используется объект
Person
и каждый
Person
имеет имя и фамилию, то может потребоваться сравнивать фамилии и имена. Пример 6.7 показывает способ сделать это.

Поделиться:
Популярные книги

Лишняя дочь

Nata Zzika
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Лишняя дочь

Маверик

Астахов Евгений Евгеньевич
4. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Маверик

Мужчина моей судьбы

Ардова Алиса
2. Мужчина не моей мечты
Любовные романы:
любовно-фантастические романы
8.03
рейтинг книги
Мужчина моей судьбы

Развод, который ты запомнишь

Рид Тала
1. Развод
Любовные романы:
остросюжетные любовные романы
короткие любовные романы
5.00
рейтинг книги
Развод, который ты запомнишь

Кодекс Охотника. Книга XIV

Винокуров Юрий
14. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XIV

Столкновение

Хабра Бал
1. Вне льда
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Столкновение

Черный маг императора

Герда Александр
1. Черный маг императора
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Черный маг императора

Кодекс Крови. Книга V

Борзых М.
5. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга V

Любимая учительница

Зайцева Мария
1. совершенная любовь
Любовные романы:
современные любовные романы
эро литература
8.73
рейтинг книги
Любимая учительница

Адвокат империи

Карелин Сергей Витальевич
1. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
фэнтези
5.75
рейтинг книги
Адвокат империи

Боярышня Дуняша 2

Меллер Юлия Викторовна
2. Боярышня
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Боярышня Дуняша 2

Убивать чтобы жить 9

Бор Жорж
9. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 9

Новый Рал 7

Северный Лис
7. Рал!
Фантастика:
попаданцы
5.00
рейтинг книги
Новый Рал 7

Боги, пиво и дурак. Том 3

Горина Юлия Николаевна
3. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Боги, пиво и дурак. Том 3