언어/C++

[C++] iterator로 set, vector 원소 삭제하기 (cannot increment value-intialized map/set)

겜도리도리 2022. 11. 19. 17:52
반응형

개요

iterator로 set, vector 원소 삭제(earse)하는 방법에 대해 서술한다.

    for (set<int>::iterator iter = s.begin(); iter != s.end(); iter++)
    {
        if (*iter % 2 == 0)
        {
            s.erase(iter);
            iter--;
        }
    }

삭제가 잘 될줄 알았지만...

삭제가 잘 되지 않는다.

사유를 보니 erase(iter)를 하게 되면 iter가 무효화되기 때문에 연산이 먹지 않는다고 한다.

vector의 iterator여서 iter++을 하면 다음 요소로 넘어가지 않을까? 굳이 무효화해야하나?라고 생각했지만

iterator는 vector 말고도 list 등에서도 작동하므로 iter를 무효화해준다고 한다.

https://stackoverflow.com/questions/8997503/map-set-iterator-not-incrementablemap-set-iterator-not-incrementable

 

map/set iterator not incrementablemap/set iterator not incrementable

Driver::~Driver() { AutoCritSec acsDriverList(m_csDriverList,true); DRIVERLIST::iterator it = m_DriverList.begin(); for(;it!=m_DriverList.end();it++) { if (it->second ==...

stackoverflow.com

#include<iostream>
#include<set>
using namespace std;

int main()
{
    set<int> s;
    s.insert(1);
    s.insert(2);
    s.insert(3);
    s.insert(4);
    s.insert(5);

    int a = 2;

    for (set<int>::iterator iter = s.begin(); iter != s.end();)
    {
        if (*iter % 2 == 0)
        {
            iter = s.erase(iter++);
        }
        else
        {
            iter++;
        }
    }

    for (auto e : s)
    {
        cout << e << ' ';
    }

    return 0;
}

이렇게 삭제 연산을 한 뒤 iter++을 통해 다시 iter에 올바른 값을 넣어주면 정상작동한다.

for문에 iter++을 밑으로 내려준 모습에 유의.

짝수 원소만 잘 삭제된 모습

    for (vector<int>::iterator iter = v.begin(); iter != v.end();)
    {
        if (*iter % 2 == 0)
        {
            iter = v.erase(iter);
        }
        else
        {
            iter++;
        }
    }

vector에서도 잘 적용가능하다.

erase(iter)의 반환값은 그 다음 요소를 가르키는 iterator이므로 iter++과 사실상 역할이 같다.

    for (set<int>::iterator iter = s.begin(); iter != s.end();)
    {
        if (*iter % 2 == 0)
        {
            s.erase(iter++);
        }
        else
        {
            iter++;
        }
    }

단 iter로 받지 않고 erase만 할 경우에는 앞서 말했듯 iter가 erase에 들어가면 무효화되기 때문에

삭제된 요소를 가리키는 iter는 더이상 사용하지 못하므로 반드시 iter 뒤에 ++을 붙여줘 가리키는 대상을 바꿔주어야 한다.

 

 

반응형