小心使用std::map erase()

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;
    }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章