}
}
Обсуждение
map— это ассоциативный контейнер, который отображает ключи на значения, предоставляет логарифмическую сложность вставки и поиска и постоянную сложность удаления одного элемента. Обычно разработчики используют отображение для хранения объектов по их ключам типа string. Именно это делает пример 6.6. В этом случае отображаемый тип является строкой, но он может быть почти чем угодно.
Отображение объявляется вот так.
map
typename Value, // Тип значения
typename LessThanFun = std::less, // Функция/функтор,
// используемые для сортировки
typename Alloc = std::allocator > // Распределитель памяти
Keyи Value— это типы ключа и связанного значения, которые хранятся в отображении. LessThanFun— это функция или функтор, который принимает два аргумента и возвращает истину, если первый меньше, чем второй. По умолчанию используется стандартный функтор less. Alloc— это распределитель памяти, и по умолчанию используется стандартный.
Использование mapдовольно просто. Объявите тип ключа и значения вот так.
map strMan;
В результате будет создан map, в котором и ключ, и значение имеют тип string. С помощью operator[]поместите в отображение объекты, что интуитивно и легко читаемо.
strMap["Monday"] = Montag";
strMap["Tuesday"] = "Dienstag";
strMap["Wednesday"] = "Mittwoch"; // ...
В результате в mapбудут вставлены элементы с индексом (например, "Monday") в качестве ключа и правым операндом в качестве значения. Они хранятся в порядке, определяемом параметром шаблона LessThanFun, и если он не указан, то mapиспользует std::less.
Чтобы получить значения из map, используйте operator[]в правой части присвоения, как здесь.
wedInGerman = strMap["Wednesday"];
В манере всех стандартных контейнеров значение, связанное с ключом "Wednesday", с помощью operator=копируется в объект wedInGerman.
operator[]— это удобный способ вставки или обновления элементов или получения значений из map, но он имеет побочный эффект, который может оказаться неожиданным. Строго говоря, operator[k]возвращает ссылку на значение, ассоциированное с k— независимо от того, существует ли kв mapили нет. Если kуже находится в map, то возвращается ассоциированное с ним значение. Если нет, то kвставляется, а затем используется конструктор по умолчанию, который создает объект значения для этого ключа. Чтобы сделать это более понятным, рассмотрим, что делает следующий код.
map mapZipCodes; // Сейчас здесь ноль элементов
string myZip = mapZipCodes["Tempe"]; // В map пока что нет элементов,
// но чему теперь равно count()?
Что находится в myZipи сколько теперь элементов в mapZipCodes? Так как operator[]вставляет указанный ключ, если он не существует, myZipсодержит пустую строку, а в mapZipCodesсодержится один элемент. Это может оказаться нежелательно, но независимо от вашего желания помните, что operator[]не является const-методом: всегда есть вероятность того, что он изменит состояние map, добавив узел.
Метод insertпредоставляет альтернативный метод добавления пар в отображение, insertвыполняет строгую вставку, а не вставку/обновление, как operator[]. При использовании map (но не multimap, который может содержать дублирующиеся ключи) insert, если ключ уже существует, не делает ничего. По сравнению с ним operator[], если ключ уже существует, заменяет значение объекта для этого ключа на новое.
Но синтаксис вставки требует несколько большей работы, чем operator[], и он связан с тем, как mapхранит данные. Рассмотрим строку из примера 6.6.
strMap.insert(std::make_pair("Sunday", "Sonntag"));
ma pхранит пары ключ/значение в объекте pair, pair— это простой вспомогательный шаблон класса (объявленный в и включенный в ), который хранит два значения двух типов. Чтобы объявить pairиз двух string, сделайте так.
pair myPair;
Первый и второй элементы в pairдоступны по открытым членам firstи second. При использовании для доступа к элементам mapоператора operator[]обычно работать с pairне приходится, но в случае со многими другими методами это придется делать, так что следует знать, как создавать и использовать объекты pair. Например, итераторы разыменовываются в простые объекты pair, так что при их использовании, как это делается в примере 6.6, следует знать, как получить ключ и его значение.
Читать дальше