2013-03-12 61 views
4

我對std::multimap容器有一些頭痛,我想知道什麼是實現我的目標的正確方法。基本上,這是我的SSCCEstd :: multimap和equal_range

#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的範圍內

更改其他行的關鍵,因爲「references and iterators to the erased elements are invalidated」,我怎麼能刪除這些的Elemen TS?我應該在某個容器中推送特定的迭代器並在循環結束後迭代它嗎?我看到this answer,但它似乎有點hackish /醜陋/容易出錯/等...

關於2,由於「愚蠢」的方法不會(顯然)工作,什麼是一個很好的方法來實現什麼我需要?一旦我解決了第一個問題,我可以刪除這些元素並插入新的元素,但是如果我錯誤地插入了一個與我剛刪除的元素相同的元素的項目,那麼這可能是否會讓迭代陷入混亂? ..

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

回答

5

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; 
} 
+0

不錯的主意!謝謝 :) – 2013-03-13 01:25:13