
std::map — поиск и вставка в одну строку
Существует эффективный способ решения одной стандартной для контейнера std::map проблемы, а именно выполнение следующей последовательности: Выполнить поиск элемента в контейнере std::map и, если искомого элемента не существует, вставить его.
Если вы использовали контейнер std::map, то наверняка уже столкнулись с одной проблемой, а именно:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
using my_map_t = std::map<std::string, int>; // Возвращает true только если был вставлен новый элемент; // если искомый элемент существует, возвращает false. bool InsertNewItem(const my_map_t& mapContainer, const std::string& key, int value) { bool isAlreadyExisted = false; if (mapContainer.find(key) != mapContainer.end()) { isAlreadyExisted = true } else { mapContainer[key] = value; } return !isAlreadyExisted; } |
Дело в том, вы не можете просто выполнить следующую строку, так как в этом случае вы не можете сказать, было ли значение вставленно или же оно уже было в контейнере до этого:
1 |
thisMap[key] = value; |
Но приведенный выше код фунции InsertNewItem()
кажется немного неаккуратным для такой простой задачи. Однако, STL уже предоставляет нам решение этой проблемы. Контейнер std::map уже имеет перегруженную версию функции-члена insert()
:
1 2 3 4 5 6 7 8 9 10 |
// std::map // pair<iterator,bool> insert (const value_type& val); // Возвращает true только если в контейнер был вставлен новый элемент; // если элемент уже существует, возвращает false. bool InsertNewItem(const my_map_t& mapContainer, const string& key, int value) { std::pair<my_map_t::iterator, bool> res = mapContainer.insert(my_map_t::value_type(key, value)); return res.second; } |
Функция std::map::insert()
возвращает std::pair
. Первый член этой пары является итератором. Он всегда указывает на элемент в std::map, причем не важно был ли этот элемент только что вставлен или уже был до этого в контейнере. Второй элемент пары представляет собой булевское значение, равное true, если соотв. ключ был найден до вставки нового элемента. Проще говоря, эта функция реализует следующую семнтику: «Скажите мне, если этот ключ уже существует в контейнере, и, если не существует, то добавь в контейнер новый элемент с этим ключем».