1. std::remove 동작
remove함수는 컨테이너의 특정 원소를 제거할 때 사용한다. remove를 사용하기 위해선 algorithm 헤더 파일이 필요하다. 아래는 vector의 원소를 제거하는 예제 코드다.
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<int>::iterator last = std::remove(values.begin(), values.end(), 4);
return 0;
}
C++
복사
values의 원소 중 4를 제거했다. remove 후에는 남은 원소들의 마지막 원소 다음 위치의 반복자를 반환한다. 따라서 last는 9 다음 원소를 가리키게 된다. remove 사용 시 주의할 점은 제거 후 컨테이너의 원소 개수는 변하지 않는다는 것이다. remove 동작은 제거할 원소 위치에 뒤에 있는 원소들을 앞으로 복사하여 덮어쓰는 것이다. 이런 동작으로 인해 last가 가리키는 원소의 값을 확인해보면 9다. last는 values[9]를 가리키게 되는데 values[8]에 9를 덮어쓴 후 여전히 원래 값을 가지고 있기 때문이다. 원소 제거 후 컨테이너의 크기까지 줄이고 싶다면 erase함수를 사용해야 한다.
2. std::erase 동작
erase는 원소 제거 후 컨테이너의 원소 개수를 제거한 원소 수만큼 줄인다. capacity는 변하지 않는다.
#include <vector>
int main()
{
std::vector<int> values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<int>::iterator erased = values.erase(values.begin() + 5);
return 0;
}
C++
복사
values의 5번 인덱스에 해당하는 원소를 제거한다. erase도 remove처럼 반복자를 반환하는데 제거된 원소가 있던 위치의 반복자를 반환한다. 제거된 원소의 위치는 5번 인덱스이므로 erased는 values[5]를 가리키는 반복자다. 제거 후엔 remove처럼 제거된 원소 뒤의 원소들을 앞으로 복사하여 덮어쓴다. 따라서 erased가 가리키는 위치에 저장된 값은 6이다. erase는 원소 개수를 줄이므로 values의 size는 9가 된다.
3. std::remove와 std::erase 활용
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> values = {4, 5, 8, 2, 6, 3, 7, 1, 0, 2, 3, 6, 1, 8};
std::vector<int>::iterator erased =
values.erase(std::remove_if(values.begin(),
values.end(),
[](const int &value) { return (value > 4); }),
values.end());
return 0;
}
C++
복사
위 코드는 remove_if를 이용해 4보다 큰 원소들을 제거 후, 남은 원소들 개수에 맞게 컨테이너의 원소 개수를 줄인다. 이때 erased는 제거 후 남은 원소들 중 마지막 원소의 다음 원소를 가리킨다. erase는 반복자를 이용해 특정 위치나 범위를 지정하는 것만 가능하고 값이나 특정 조건을 이용해 제거할 원소를 지정하는 것은 불가능하다. 조건식으로 제거할 원소를 지정하기 위해 remove_if를 사용했고 컨테이너 원소 개수를 줄이기 위해 erase를 사용했다.