auto& kphist = this->kphist;
for (auto& it : kphist) {
it.second.aging(); // EXC-BAD-ACCESS
if(it.second.age > LAST_DAY){
kphist.erase(it.first);
continue;
}
}kphist是私人成员。
Class A{
private:
unordered_map<int, KeyPointHistory> kphist;
} 调试器显示kphist中的所有项都是有效的,如何在for循环中出现错误引用。什么可能会出错?
发布于 2015-04-10 22:22:26
从std::unordered_map::erase():对擦除元素的引用和迭代器无效。其他迭代器和引用不会失效。因此,不能在for循环的范围内使用std::unordered_map::erase() (因为这将尝试增加无效的迭代器)。
为了避免递增无效的迭代器,您可以先增量,然后使用原始迭代器擦除:
for(auto i=map.begin(),end=map.end(); i!=end; ) { // no increment here
auto it=i++; // but here instead
if(must_remove(it))
map.erase(it);
}实际上,由于erase()将迭代器返回给下一个元素,您可以避免额外的迭代器it (感谢Hurkyl在注释中指出了这一点):
for(auto i=map.begin(),end=map.end(); i!=end; ) { // no increment here
if(must_remove(i))
i = map.erase(i); // but here
else
++i; // or here instead
}不需要列出要删除的元素的列表.
顺便说一句,为什么不使用std::map (而不是std::unordered_map),因为您的密钥是int (这很容易订购)。另外,为什么要对同名的成员变量进行引用kphist?
发布于 2015-04-10 22:04:49
您不能在遍历内容/迭代器时擦除它,您也不应该这样做。
将元素索引保存在不同的容器中,完成后循环遍历,然后删除所得到的元素。
什么可能会出错?
所有的一切!
发布于 2015-04-10 23:45:17
您可以通过直接将迭代器传递到要删除的项从unordered_map中擦除。当您这样做时,erase()返回后续的迭代器,所以您可以这样做:
for (auto pos = kphist.begin(); pos != kphist.end(); ) {
it.second.aging();
if(it.second.age > LAST_DAY)
pos = kphist.erase(it);
else
++pos;
}作为奖励,这可能比传递要擦除的键要快一些--因为你提供了迭代器,它可以直接到达要删除的项,而不是重新散列键以找到您已经知道的位置。
https://stackoverflow.com/questions/29571290
复制相似问题