小心使用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;
    }


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