我的要求是从多图而不是“密钥”中删除一个“值”。
密钥可能有多个值,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;
}
}
我做错了吗? 在这方面的任何帮助都非常感谢。
答案 0 :(得分:1)
最重要的是,当您打算致电erase(j->second)
时,请致电erase(j)
。你没有删除j
指向的多图的元素,你正在删除其键等于j
所指向的元素值的所有元素(sessionid
})。我希望这没什么。
另外:在equal_range
循环完成后再次调用erase
- 使用已擦除迭代器的效果未定义,因此如果删除了第一个迭代器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
返回一个空范围(两个相等的迭代器值),因此您的其他循环无论如何都不会执行任何操作。
答案 1 :(得分:0)
如果删除了i.first
或i.second
,则迭代器将失效,暗示未定义的行为。