2016. 2. 28. 00:05ㆍ프로그래밍/Effective STL
정말 중요한 핵심
remove는 어느 것도 "진짜로" 없애지 않는다. 없앨 수 없기 때문이다.
책에서 이 문장을 아주 중요하게 두 번이나 반복하고 있다.
님아.. 근데 list는 지워지긴 하잖아욤.... 이건 멤버 함수라 이건가?
예시
우리가 자주 사용하는 vector를 예로 들면,
1 2 3 4 5 6 7 | vector<int> intVec; const int VEC_SIZE = 10; intVec.reserve(VEC_SIZE); for (int i = 0; i < VEC_SIZE; i++) { intVec.push_back(i / 2); } | cs |
이렇게 선언했다 치면 0011223344의 값이 순차적으로 백터에 들어간다.
실제 3의 값을 지우고 싶다면 간단히 생각해서 remove 함수를 호출하게 되는데...
값을 지워볼까?
1 | remove(intVec.begin(), intVec.end(), 3); | cs |
이렇게 하면 될 것이라 생각하지만.. 역시 모든 일은 그렇게 간단하진 않다.
결과는 0011224444가 나오게 되는데.. 이건 remove의 동작을 이해해야한다.
remove의 동작
remove의 내부 코드를 봤을 때 일단 find를 통해 해당 값을 찾고
뒤에 값을 하나씩 땡겨주는 역할을 한다. 해당 부분을 삭제하는 것이 아니고 압축시켜버리는 형태.
재귀로 계속 호출하며 해당 찾는 값을 덮어쓸 자리로 두고 뒤에 값을 계속 땡겨준다.
라이브러리 제품마다 다른데 다 땡기고 검사가 끝나고 남은 자리는 어떤 값이 채워질지는 알 수 없다.
00112244??
remove의 최종적으로 리턴되는 iterator는 첫 번째 ?를 가리키고 있다. 여기가 새로운 end iterator라 할 수 있다.
erase 같이 사용하기
erase는 해당 메모리를 정말로 삭제하는 함수로. 범위를 지정해주면 된다.
한 마디로 위에서 나오는 새로운 end iterator부터 기존 end 까지 지워주면 삭제완료.
Erase ( New End Iterator ~ Lagacy End Iterator ) 느낌인 것 같다.
1 | intVec.erase(remove(intVec.begin(), intVec.end(), 2), intVec.end()); | cs |
0011223344 -> 00114444??(remove : 2가 삭제되지 컨테이너가 정말 삭제되진 않음) -> 00114444(erase : 컨테이너 삭제)
list는?
erase-remove 합성문 대신 remove 멤버 함수가 효율적이다.
1 2 | intList.remove(3); // so simple | cs |
'프로그래밍 > Effective STL' 카테고리의 다른 글
[effective STL] 항목 34 : 정렬된 범위 동작 알고리즘들 (0) | 2016.03.19 |
---|---|
[effective STL] 항목 33 : remove 같은 알고리즘 사용할 때 포인터 컨테이너 주의 (0) | 2016.02.29 |
[effective STL] 항목 31 : 정렬시 선택 사항들을 제대로 파악 (2) | 2016.02.27 |
[effective STL] 항목 30 : 알고리즘의 데이터 기록 범위는 충분히 크게 잡자. (0) | 2016.02.20 |
[effective STL] 항목 28 : reverse_iterator 쓸 때 base() 잘 쓰기 (0) | 2016.02.19 |
[effective STL] 항목 27 : const_iterator -> iterator는 distance와 advance를 사용하자. (2) | 2016.02.15 |
[effective STL] 항목 26 : 여러 iterator 중 쓸만한 것은 결국 iterator (2) | 2016.02.10 |