아래는 vector에 1~5까지의 5개의 int 데이타를 넣고 reverse_iterator를 써서 3을 가리키게 한후, iterator하나를 revserse_iterator의 기점으로 세팅하는 코드이다.
vector<int> v;
v.reserve(5); // 미리 할당 EffectiveSTL14 를 참고
for( int i=1; i<=5; i++) {
v.push_back(i);
}
// 3을 가리킨다.
vector<int>::reverse_iterator ri = find(v.rbegin(), v.rend(), 3);
// i가 ri의 기점과 같게 한다.
vector<int>::iterator i(ri.base());
위의 코드를 도식화 해서 표현하자면 이렇게 된다.
rend() rbegin()
↓ ↓
┌─┬─┬─┬─┬─┐
│1│2│3│4│5│
└─┴─┴─┴─┴─┘
↑ ↑
begin() end()
(크아 그리느라 죽는줄 알았어!)
insert나 erase는 reverse_iterator를 인자로 받아들이지 않는 경우가 있기 때문에 위의 경우와 같이 reverse_iterator를 사용하다가 insert나 erase가 필요한 경우는 iterator로 변환을 해야 한다. 그 때 사용하는 메소드가 바로 base이고 위의 그림과 같은 대응되는 위치를 갖는다.
ri와 i, rbegin()과 end() 등의 위치가 미묘하게 다른것을 볼수 있는데
insert를 할 경우에는 저런 관계가 아주 정확하게 성립된다. STL의 세계 에서의 요소 삽입은 반복자가 가르키는 위치의 바로 앞에서 이루어 진다는 점을 생각할때 3을 가르키는 ri의 기점 반복자가 4를 가리키고 있으므로 ri의 base() 호출에 의한 i로 insert() 를 호출시 정확히 원하는 위치인 3과 4 사이에 데이타를 삽입하게 된다.
하지만 erase는 다르다.
위의 그림을 볼때 ri가 가르키는 데이타를 삭제해서 나타나는 원하는 결과는 3이 삭제되는것일 것이지만 base()함수를 이용해 기점 반복자 i를 얻어 erase()를 호출하면 4가 삭제되어 버릴것이다.
이런 erase관련 문제를 해결하기 위해서 reverse_iterator의 위치 값을 하나더 증가시킨뒤 base() 를 호출하는 방법을 생각할수 있다.
v.erase( (++ri).base() ); // ri가 가르키는 요소를 삭제한다.
즉 ri는 (++ri)에 의해서 2를 가르키게 되고 ri의 base() 결과인 i는 3을 가르키게 된다.
base()로 기점 반복자를 얻은뒤 그 기점 반복자의 위치를 변경하는 것도 방법이 될수 있지만 vector 와 string에서 문제가 발생한다. 자세한 내용은 책 참조