删除C++ STL multimap中特定键的条目

San*_*osh 2 c++ stl

我有这个示例代码将条目插入到multimap.我试图删除指定键的特定条目.但是这段代码进入无限循环.有人可以帮我这个代码吗?

#include <iostream>
#include <map>
#include <string>
using namespace std;

int main()
{
    multimap<string, string> names;
    string n;

    names.insert(pair<string, string>("Z", "F"));
    names.insert(pair<string, string>("Z", "A"));

    names.insert(pair<string, string>("S", "T"));
    names.insert(pair<string, string>("S", "A"));
    names.insert(pair<string, string>("S", "J"));

    names.insert(pair<string, string>("D", "H"));
    names.insert(pair<string, string>("D", "W"));
    names.insert(pair<string, string>("D", "R"));

    multimap<string, string>::iterator p;


    p = names.find("Z");
    if(p != names.end()) { // found a name
        do {
            cout << n << ", " << p->second;
            cout << endl;
            if (p->second.compare("A") == 0) {
                names.erase(p);
                p++;
            } else {
                p++;
            }
        } while (p != names.upper_bound("Z"));
    }
    else{
        cout << "Name not found.\n";
    }

    p = names.find("Z");
    if(p != names.end()) { // found a name
        do {
            cout << n << ", " << p->second;
            cout << endl;
        } while (p != names.upper_bound("Z"));
    }
    else{
        cout << "Name not found.\n";
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在上面我正在查找使用键值"Z"并想要删除"A".

Dav*_*own 5

multimap::erase 使任何迭代器无效到擦除元素,所以行

names.erase(p);
p++;
Run Code Online (Sandbox Code Playgroud)

擦除p,从而使其无效,然后尝试增加无效的迭代器.您可以通过复制p到临时的递增p,然后擦除临时迭代器来解决此问题.

multimap<string, string>::iterator temp = p;
++p;
names.erase(temp);
Run Code Online (Sandbox Code Playgroud)

或者,如果您正在使用C++ 11,则multimap::erase返回容器中的下一个迭代器

p = names.erase(p);
Run Code Online (Sandbox Code Playgroud)

编辑:上面实际上并不是你的无限循环的来源.在第二个循环中,你不会增加p,所以它会永远消失.然而,它仍然是你应该修复的东西,因为它可能导致不可预测和难以追踪错误.