std::map在过去的旧的实现中,map::erase()的返回值类型为void,在遍历过程中,如果要erase,要格外小心,因为iter会在某些情况下失效。
std::map<int, int> mapTest;
mapTest.insert(std::make_pair(1, 1));
mapTest.insert(std::make_pair(2, 2));
mapTest.insert(std::make_pair(3, 3));
mapTest.insert(std::make_pair(4, 4));
mapTest.insert(std::make_pair(5, 5));
// Wrong! to erase the last iter
std::map<int, int>::iterator iter = mapTest.begin();
for(; iter != mapTest.end(); ++iter)
{
int key = iter->first;
printf("%d\t", key);
if(key == 5)
{
mapTest.erase(iter);
}
}
// Wrong:
std::map<int, int>::iterator iter = mapTest.begin();
for(; iter != mapTest.end(); )
{
int key = iter->first;
printf("%d\t", key);
if(key == 5)
{
std::map<int, int>::iterator iterTmp = iter;
mapTest.erase(iterTmp);
++iter;
continue;
}
++iter;
}
// Correct:
std::map<int, int>::iterator iter = mapTest.begin();
for(; iter != mapTest.end(); )
{
int key = iter->first;
printf("%d\t", key);
if(key == 5)
{
std::map<int, int>::iterator iterTmp = iter;
++iter;
mapTest.erase(iterTmp);
continue;
}
++iter;
}
// Correct
std::map<int, int>::iterator iter = mapTest.begin();
for(; iter != mapTest.end(); )
{
int key = iter->first;
printf("%d\t", key);
if(key == 5)
{
mapTest.erase(iter++);
continue;
}
++iter;
}
在新版的实现中,std::map::erase返回值类型为std::map::iterator,返回下一个iterator,那我们在以上的情况中,就可以写成:
std::map<int, int>::iterator iter = mapTest.begin();
for(; iter != mapTest.end(); )
{
int key = iter->first;
printf("%d\t", key);
if(key == 5)
{
iter = mapTest.erase(iter);
continue;
}
++iter;
}
转载于:https://blog.51cto.com/yongkai/1625613