std :: multimap и equal_range

У меня есть некоторые головные боли с std::multimap Контейнер и я хотел бы знать, что будет правильным способом для достижения моей цели. В основном, вот мой SSCCE:

#include <iostream>
#include <map>

int main ()
{
typedef std::multimap<int, int> CollectionType;
typedef std::pair<CollectionType::iterator, CollectionType::iterator> RangeType;

CollectionType multiMap;

multiMap.insert(std::make_pair(1, 1));
multiMap.insert(std::make_pair(1, 2));
multiMap.insert(std::make_pair(2, 3));
multiMap.insert(std::make_pair(2, 4));
multiMap.insert(std::make_pair(2, 5));
multiMap.insert(std::make_pair(3, 1));

RangeType range = multiMap.equal_range(2);
for (CollectionType::iterator iterator = range.first; iterator != range.second; ++iterator)
{
if (iterator->second == 4)
{
//multiMap.erase(iterator);//ISSUE 1
}
else
{
//iterator->first = -1;//ISSUE 2
}
}

return 0;
}

Как вы можете видеть выше, мне нужно выбрать диапазон multimap для данного ключа, а затем:

  1. Мне нужно стереть определенные строки из диапазона
  2. Мне нужно изменить ключ других строк из диапазона

Что касается 1, так какссылки и итераторы на стертые элементы становятся недействительными«, как я могу удалить эти элементы? Должен ли я вставить определенные итераторы в некоторый контейнер и перебрать его после завершения цикла? Я видел этот ответ, но это кажется немного хакерским / уродливым / склонным к ошибкам / и т.д …

Что касается 2, так как «тупой» подход не будет (очевидно) работать, какой будет хороший подход для достижения того, что мне нужно? Я мог бы удалить элементы и вставить новые вместо них, как только решу проблему 1, но разве это не испортит итерацию, если, скажем, я ошибочно вставлю элемент с тем же ключом, что и тот, который я только что удалил ?. ..

int second = iterator->second;
localEdges.smarter_erase(iterator);
localEdges.insert(std::make_pair(-1, second));

3

Решение

erase возвращает итератор, поэтому сбросьте итератор на него, и он останется действительным.

Просто вставьте новый ключ, удалив оригинал

http://ideone.com/0Pr6Qc:

#include <iostream>
#include <map>

void printMultimap(const std::multimap<int, int>& multiMap)
{
std::cout << "MultiMap:\n";
for (const auto& pair : multiMap)
{
std::cout << pair.first << ":" << pair.second << "\n";
}
}

int main()
{
std::multimap<int, int> multiMap;
multiMap.insert(std::make_pair(1, 1));
multiMap.insert(std::make_pair(1, 2));
multiMap.insert(std::make_pair(2, 3));
multiMap.insert(std::make_pair(2, 4));
multiMap.insert(std::make_pair(2, 5));
multiMap.insert(std::make_pair(3, 1));

printMultimap(multiMap);

auto range = multiMap.equal_range(2);
for (auto iterator = range.first; iterator != range.second;)
{
if (iterator->second != 4)
{
multiMap.insert(std::make_pair(-1, iterator->second));
}
iterator = multiMap.erase(iterator);
}

printMultimap(multiMap);

return 0;
}
4

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector