std :: multimap和equal_range

时间:2013-03-12 01:40:52

标签: c++ iterator range multimap erase

我对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. 中的某些行
  3. 我需要更改范围
  4. 中其他行的键

    关于1,自“references and iterators to the erased elements are invalidated”以来,我该如何删除这些元素?我应该在某个容器中推送特定的迭代器,并在循环结束后迭代它吗?我看到了this answer,但它似乎有点hackish /丑陋/容易出错等等......

    关于2,由于“愚蠢”的方法(显然)不会起作用,实现我需要的是什么样的好方法?一旦我解决问题1,我就可以删除元素并在其位置插入新元素,但是如果我错误地插入一个与我刚删除的那个键相同的键的项目,那么这可能会搞乱迭代。 ..

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

1 个答案:

答案 0 :(得分:4)

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