std::multimap and equal_range
c++, erase, iterator, multimap, range
Solution
`erase` returns an iterator, so reset your iterator to that and it will continue to be valid.
Just reinsert with the new key, erasing the original
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;
}
Problem
I'm having some headaches with the `std::multimap` container and I wish to know what would be the proper way to achieve my goal. Basically, here is my 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; } ``` As you can see above, I need to select a range of the `multimap` for a given key and then: - I need to erase certain rows from the range - I need to change the key of other rows from the range Regarding 1, since "references and iterators to the erased elements are invalidated", how can I remove those elements? Should I push the specific iterators in some container and iterate over it once the loop is over? I saw this answer, but it seems a bit hackish / ugly / error prone / etc... Regarding 2, since the "dumb" approach won't (obviously) work, what would be a good approach to achieve what I need? I could remove the elements and insert new ones in their place, once I solve issue 1, but wouldn't that perhaps mess up the iteration if, let's say I mistakenly insert an item with the same key as the one I just removed?... ``` int second = iterator->second; localEdges.smarter_erase(iterator); localEdges.insert(std::make_pair(-1, second)); ```