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

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

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

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

key_type

Это тип ключа. В string map, объявленном как map, key_type должен быть string.

mapped_type

Это тип значения, на которое отображается ключ. В string map, объявленном как map, mapped_type должен быть MyClass*.

value_type

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

Табл. 6.1. map и multimap

Методmap, multimap или обаПоведение
T& operator[] (const key_type& k)mapВозвращает ссылку на объект значения, сохраненный с ключом k. Если k в map отсутствует, то он добавляется, а объект значения создается с помощью конструктора по умолчанию
iterator insert(const value_type& v) pair 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::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 работает аналогично, но с противоположным условием.

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

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