반응형
개요
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를 무효화해준다고 한다.
#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 뒤에 ++을 붙여줘 가리키는 대상을 바꿔주어야 한다.
반응형
'언어 > C++' 카테고리의 다른 글
[Unreal] 콘텐츠 브라우저에서 C++ 클래스가 보이지 않을 때 (0) | 2023.03.28 |
---|---|
[C++] 미정의 동작 (0) | 2023.03.21 |
no viable conversion from 'value_type' (aka 'char') to 'string' (aka 'basic_string<char, char_traits<char>, allocator<char> >') (0) | 2022.11.05 |
[C++] string 덧셈 (0) | 2022.09.17 |
[C++] 상수 및 비상수 멤버 함수에서 코드 중복 현상 피하기 (0) | 2022.07.22 |