2008.07.26 21:41 책 정리/Effective STL
내가 STL에 조예가 깊어서 글을 남기는 것이 아니라, Effecitve STL 을 공부하는 사람들이 이 글을 보고, 도움이 되었으면 하는 생각과, 혹시 내가 틀린것이 있다면 지적해 주시지 않을까 란 생각으로 글을 올리는것임을 미리 밝힙니다.  - 최익필


26항목 부터 반복자에 대한 이야기를 진행 한다. 반복자란 말을 딱 들으면 뭐지.. 란 생각을 한다. 뭐야 도데체? 반복자라 하면 잘 모르겠고 iterators 라고 하면 아~ 하고 느낌이 팍팍 올 것이다.

iterators 에는 iterator ,const_iterator, reverse_iterator. const_reverse_iterator 처럼 4가지 종류의 iterators가 있는데, 왜 4개나 있고, 어떤 관계이며, 변환이 가능한지, 알고리즘에 어떻게 사용 할지, 컨테이너와 이 iterators 간에 어떻게 소통하는지 .. 배워 볼 것이라 한다.

아.... 그리고 문자 스트림을 읽을 때 사용하는 istream_iterator 와 istreambuf_iterator 에 대해서도 이야기 해준다고 한다.(아싸라비아 콜롬비아 땡잡았다!)


우선 4종류의 iterator가 어떤 속성인지에 대한 이야기를 해볼까 한다. 뭐 .. 키워드만 보면 어떤거구나 싶을 듯 하다. 만약 container<T> 라고 정의된 컨테이너가 있다면

iterator 는 T* 순방향
const_iterator 는 const T* 순방향
reserve_iterator 는 T* 역방향
const_reserve_iterator 는 const T* 역방향

이다. 뭐 다들 감으로 알고 있을 듯 싶으니 바로 본론으로 넘어간다.

이것들은 언제 사용 할까?
우선 두부분으로 나눌수 있는데 바로 const 붙은 녀석과 안붙은 녀석이다. const의 용도와 똑같이 사용 할 때 사용하는 iterator 이다. const를 왜 사용하는지 물어 본다면, http://ikpil.tistory.com/113 확인해 보고..


그런데 왜! 왜! iterator 가 더 쓸만하다고 할까?
일단 .. 제목에 낚였다. 무조건 좋은게 아니다. 하긴 .... 표준 위원회에서 만들었다면 그 만한 사유가 있겠지.  크게 두가지 경우에 더 쓸만한데 우선 첫번째 부터 소개 한다.

첫번째
데이터를 Containers에 담을 때, 삭제 하려 할 때 매개변수는 const_iterator 보단 iterator 만을 사용한다. 그렇기 때문에 자신이 const_iterator 을 쓰고 있고, 그 자리에 데이터를 넣으려 할 때는 (.. casting 해줘야 하는데, ... 이건 다음에 이야기하고..) 넣지 못하는 사태가 발생한다.


두번째

              const_iterator
         ↗                       ↖
iterator                              ↖  base()
         ↘↖base()                   ↖
              reverse_iterator    →   const_reverse_iterator

위 그림은 이런것을 말했던 것이다.

화살표 방향만 있는것은 컴파일러에 의하여 암시적으로 바뀐다. http://ikpil.com/539 참조, 그리고 base() 라고 한 부분은 명시적으로 사용자가 바꾸어 주어야만 한다.

그래서 다른 iterator 끼리 비교 하려 할 때, const_iterator 와 그냥 iterator 비교 될 때 자동으로 변환해 주는 컴파일러가 있다. 그래서,  if( iterator == const_iterator )  된다면, if( const_iterator == const_iterator ) 으로 암시적으로 처리 하게 하고, 두개가 비교 한다.,

하지만 안 그런 컴파일로도 있다...(제발 컴파일러 개발자 여러분.. STL 표준을 .. 지킵... 음.. 제가 잘못했습니다. 그냥 쓸게요. ) 이때는 비멤버 함수로 선언하여, 두 개의 매개변수를 받게 하면 .. 처리(swap 함수를 어떻게 클래스에 호환되게 하는지 생각하면 손쉽게 구현 가능하다) 할수 있고 다른 방법으로는 const_iterator == iterator 식으로 회피해 가는 방법이 있다.

왜냐하면 const_iterator 에는 operator==를 정의해 두었기 때문이다.


또한 iterator 와 const_iterator 끼리 + 나 - 를 사용하여, 비교 할 수가 있는데, .. 뭐 예를 들어 코드로 써주겠다.

하핫. . MSVC2005는 .. iterator 를 컴파일러가 지원해 준다. ㅋㅋ 만약 이게 컴파일이 안된다면,
아래 코드 처럼 사용하길 바란다.


즉 컴파일이 안된다면 const_iterator 를 좌측에 두어 비교 하면 된다는 것이다. 가끔 effective STL 을 보고 있노라면, .. 감동을 느낀다. .. 스콧 마이어스 나 곽용재 씨나.. 감사합니다.  나중에 성공하면 소심하게 한턱...


이것만은 잊지 말자!
1. Container에 insert() 하거나 erase() 할 때, iterator 가 제일 쓸만하다.
2. 만약 const_iterator 와 iterator 비교가 호환이 안된다면 const_iterator 를 좌측에 두어 연산 시키자.


관련링크
http://www.joinc.co.kr/modules/moniwiki/wiki.php/article/STL_iterator <-- 대략적인 iterator 설명
http://compstat.chonbuk.ac.kr/rightway/designpatterns/iterator.html <-- iterator 패턴
http://rein.upnl.org/wordpress/archives/995 <-- 다른 종류의 iterator를 알려 준다.
http://ideathinking.com/blog/?p=66 <-- boost 의 iterator 설명

posted by 농사를 짓는 게임 프로그래머 최익필

댓글을 달아 주세요