스토리텔링 개발자

[Effective STL] 26. 기본 iterator 선호하기 본문

개발/Effective STL

[Effective STL] 26. 기본 iterator 선호하기

김디트 2024. 12. 11. 10:47
728x90

항목 26. const_iterator나 reverse_iterator, const_reverse_iterator도 좋지만 역시 쓸만한 것은 iterator이다

 

 

 

iterator들의 관계
  • vector<T>에서 제공되는 함수들을 우선 보도록 하자.
iterator insert(iterator position, const T& x);
iterator erase(iterator position);
iterator erase(iterator rangeBegin, iterator rangeEnd);
  • 모두 iterator를 매개변수로 받아들인다.
  • 이제, 네 가지 반복자 사이의 상호 변환 관계를 그림으로 보도록 하자.

화살표는 암묵적(implicit) 변환이 가능하다는 뜻이다. 함수가 적힌 화살표는 함수 변환만 가능하다는 뜻이다.

  • const_iterator가 iterator로, const_reverse_iterator가 reverse_iterator로 암묵적 변환할 방법은 없다.
    • 즉, const_iterator나 const_reverse_iterator만 가지고는 STL 표준 컨테이너의 멤버 함수를 사용하는 데 문제가 생길 수 있다는 뜻이다.
    • 고로 요소 삽입 위치나 삭제 위치를 지정하거나 하는 데 있어서 상수 반복자는 대개 쓸모가 없다.

 

 

 

상수 반복자의 필요성
  • 알고리즘은 자신이 사용하는 반복자의 종류에 상관없이 동작한다.
    • 그러므로 상수 반복자는 알고리즘에서 잘 쓰일 수 있다.
  • 또한, 컨테이너의 많은 멤버 함수에서 상수 반복자를 받어들인다.
    • 오직 insert와 erase 류 함수에서 문제가 있을 뿐이다.

 

 

 

정리 : 비상수 반복자 타입(iterator)가 좋은 이유
  • 어떤 형태의 insert와 erase 멤버 함수는 무조건 iterator만을 받는다.
  • const_iterator를 iterator로 암묵적 변환할 방법이 없다.
    • 바꿀 방법이 있긴 하지만, 효율에 대한 보장을 할 수 없다.(항목 27 참조)
  • reverse_iteartor를 iterator로 변환할 수 있으나, 변환한 후 약간의 조정이 필요하다.(항목 28 참조)

 

 

 

오래된 컴파일러에서 반복자 타입을 섞어쓸 때 주의
  • iterator / reverse_iterator는 base 함수를 통해 같은 반복자로 바꿔줄 수 있으므로 문제가 없다.
  • iterator / const_iterator를 비교하는 경우에는?
deque<int> IntDeque;

IntDeque::iterator i;
IntDeque::const_iterator ci;

...

if(i == ci) ... // 반복자와 상수 반복자의 비교
  • 이 코드는 문제가 생겨서는 안 되지만..
    • 혹시! 문제가 생기는 컴파일러를 사용하고 있다면..
    • 아마 const_iterator에만 operator==를 멤버 함수로 선언해 두었기 때문일 것이다.
    • if(ci == i) ... // 순서만 바꿔줘도 해결될 것이다.
  • 오래된 컴파일러에서 문제가 생길 수 있고, 순서만으로 해결이 안 되는 상황
if(i - ci >= 3) ... // i가 ci보다 3칸 이상 앞으로 가 있을 때
// ci - i 로 바꿀 수는 없는 노릇이다..

// 아래와 같이 수정한다.
if(ci + 3 <= i) ...
  • 문제를 막기 위한 가장 쉬운 방법은 반복자 타입을 섞어 쓰지 않는 것이다.
    • 즉, 결국 const_iterator 대신 iterator를 쓰자는 결론에 닿는다.
728x90
Comments