从多重地图中删除"value"

Deleting a "value" from a multimap

本文关键字:删除 value 地图      更新时间:2023-10-16

我的要求是从多重映射中删除"值"而不是"键"。一个键可能有多个值,i希望删除特定值。我的要求类似于从链表中删除节点。

我正在使用multimap::erase()方法这样做。但是删除后,如果我尝试打印多重地图的值,则也会打印使用multimap::erase()删除的值。

下面是我的代码片段:

void Clientqueues::clearSubscription(string name,string sessionid)
{
    pair<multimap<string,string>::iterator,multimap<string,string>::iterator> i;
    multimap<string, string>::iterator j;
    i = registeredClientInfo.equal_range(name);
    if (j == registeredClientInfo.end())
            return;
    for(j=i.first;j != i.second;++j)
    {
        if((j->second) == sessionid) registeredClientInfo.erase(j->second);
    }
    for(j=i.first;j != i.second;++j)
    {
        cout<<""<<j->second<<endl;///This prints the erased values too;
    }
}

我做错了什么吗?非常感谢这方面的任何帮助。

最重要的是,当你打算称呼erase(j)时,你称呼erase(j->second)。您不会擦除 j 指向的多重映射元素,而是擦除键等于 j 指向的元素值的所有元素(即 sessionid (。我希望这没什么。

另外:在erase循环完成后再次调用equal_range - 使用擦除迭代器的效果是不确定的,所以如果你i.first擦除了第一个迭代器,那么你之后就不能再从那里开始迭代了。

请注意,这也意味着您的循环中存在一个执行erase的错误,因为在您确实调用erase的情况下,当它包含不再有效的迭代器值时,您会递增j。不幸的是,正确的代码是:

for(j=i.first;j != i.second;)
{
    if((j->second) == sessionid) {
        auto next = j;
        ++next;
        registeredClientInfo.erase(j);
        j = next;
    } else {
        ++j;
    }
}

或者,如果您愿意:

for(j=i.first;j != i.second;)
{
    auto current = j;
    ++j;
    if((current->second) == sessionid) registeredClientInfo.erase(current);
}

或者,如果该条目对于键/值对是唯一的,因此您最多只需要删除一件事,那么:

for(j=i.first;j != i.second;++j)
{
    if((j->second) == sessionid) {
        registeredClientInfo.erase(j);
        break;
    }
}

if (j == registeredClientInfo.end()) return;也不对,因为当您这样做时j未初始化。如果未找到键,则equal_range返回一个空范围(两个相等的迭代器值(,因此其他循环无论如何都不会执行任何操作。

如果您

删除了i.firsti.second则迭代器将失效,这意味着未定义的行为。