GoodDaddy : 나영이 채원이 아빠

STL 컨테이너를 순회하거나 지울때 많이 하는 실수가 삭제후 이터레이터가 무효화 되는것에 대한
실수가 참 많았습니다. 요즘은 좀 습관이 되어서 덜하지만 예전엔 꼭 한번씩 하더군요.
뭔가에 홀린듯이..

아래 세가지는 Effective STL 항목9에서 발췌한 내용인데 세가지만 명심한다면 무효화된 이터레이터때문에
고통받는 일은 없을듯 합니다.

1. 컨테이너에서 특정한 값을 가진 객체를 모두 없애려면.
컨테이너가 vector,string 혹은 deque이면, erase-remove 합성문을 쓴다.
컨테이너가 list 리면, list::remove 를 쓴다.
컨테이너가 표준 연관 컨테이너이면, erase 맴버 함수를 쓴다.

2. 컨테이너에서 특정한 술어 구문을 만족하는 객체를 모두 없애려면.
컨테이너가 vector, string 혹은 deque이면, erase-remove_if 합성문을 사용한다.
컨테이너가 list이면, list::remove_if 를 쓴다.
컨테이너가 표준 연관 컨테이너이면, remove_copy_if와 swap의 조합을 쓰든지, 컨테이너
내부를 도는 루프에서 erase를 호출하면서 erase에 넘기는 반복자를 후위 증가 연산자로 증가시킨다.

3. 루프 안에서 무엇인가를 하려면(객체 삭제도 포함해서)
컨테이너가 표준 시퀀스 컨테이너이면, 컨테이너 요소를 하나씩 사용하는 루프를 작성한다.
이때 erase를 호출할 때마다 그 함수의 반환값으로 반복자를 업데이트 하는 일을 꼭 해야 한다.
컨테이너가 표준 연관 컨테이너이면, 역시 컨테이너 요소를 하나씩 사용하는 루프를 작성한다.
이때 erase를 호출하면서 erase에 넘기는 반복자를 후위 증가 연산자로 증가시킨다.

그리고 제가 자주 하는 실수였고 최근엔 정말 조심하는것중 하나가 컨테이너 원소를 순회하면서 뭔가를
업데이트 하다가 같은 컨테이너의 다른 원소를 삭제하는 로직을 넣지 않는것입니다.
예를 들면 Update 와 Delete 의 동작은 절대 섞지 않는것..
이를 위해서 Update 중엔 객체를 바로 지우지 않고 remove 플래그만 세팅하는 등으로 처리를 합니다.
요건 원래 전체 디자인이 잘못되어 발생하는 문제이긴 하지만 자주 하게되는 실수라 아예 전 따로
처리를 합니다.
Posted by jeddli Trackback 2 Comment 0