내가 STL에 조예가 깊어서 글을 남기는 것이 아니라, Effecitve STL 을 공부하는 사람들이 이 글을 보고, 도움이 되었으면 하는 생각과, 혹시 내가 틀린것이 있다면 지적해 주시지 않을까 란 생각으로 글을 올리는것임을 미리 밝힙니다. - 최익필
우리말이 자주 어렵다고 생각한다. 글을 쓸 때, 문맥상 이상하게 이어지는 경우가 많기 때문이다. 그래서 "A는 B이다" 식으로 이야기를 하려고 한다.
이번 주제는 reverse_iterator.base() 가 어떻게 동작하는지에 대한 이야기이다. 왜냐하면 insert() 나 erase()로 reverse_iterator 를 사용할 수 없어, iterator 로 변환하는데 base() 함수를 사용 하기 때문이다.
base()로 가리킨 iterator 는 무엇을 가리키고 있는가?
실험을 통해 vector에 5개의 데이터 1,2,3,4,5 를 넣어보고, reverse_iterator 가 무엇을 가리키고 iterator 변환시 무엇을 가리키는지 알아 보겠다.
// ikpil.com or ikpil.tistory.com
#include <vector>
#include <algorithm>
#include <iostream>
typedef
std::vector<
int
> Container;
int
main(
void
)
{
Container Test( 5 );
for
(
int
i = 0; i < 5; ++i)
Test[i] = i+1;
typedef
Container::reverse_iterator Reverse_It;
typedef
Container::iterator Nomal_It;
// rit 용 3을 찾음
Reverse_It rit = std::find( Test.rbegin(), Test.rend(), 3 );
std::cout <<
"rit = "
<< *rit << std::endl;
// rit 을 it 으로 변환
Nomal_It it = rit.base();
std::cout <<
"rit.base() 해서 it을 초기화 "
<< std::endl;
std::cout <<
"it = "
<< *it << std::endl;
std::cout <<
" 그렇다 rit.base()의 it과 rit과 가르킨 대상이 다르다!"
<< std::endl;
// 다시 한번 테스트
// rit 용 2를 찾음
rit = std::find( Test.rbegin(), Test.rend(), 2 );
std::cout <<
"rit = "
<< *rit << std::endl;
// rit 을 it 으로 변환
it = rit.base();
std::cout <<
"rit.base() 해서 it을 초기화 "
<< std::endl;
std::cout <<
"it = "
<< *it << std::endl;
std::cout <<
"rit.base()는 가리킨 대상의 다음것을 it에 지정해 준다,!"
<< std::endl;
}
... 어떻게 사용 하냐고? .. 음.. 아래 코드를 보면 된다.
// ikpil.com or ikpil.tistory.com
#include <vector>
#include <algorithm>
#include <iostream>
typedef
std::vector<
int
> Container;
typedef
Container::reverse_iterator Reverse_It;
typedef
Container::iterator Nomal_It;
int
main(
void
)
{
Container Test( 5 );
for
(
int
i = 0; i < 5; ++i)
Test[i] = i+1;
// rit 용 3을 찾음
Reverse_It rit = std::find( Test.rbegin(), Test.rend(), 3 );
Test.erase((++rit).base());
// or Test.erase(--rit.base());
// 책에선 --rit.base() 는 컴파일 되지 않는 다고 하지만
// MSVC2005에서 잘 된다.
책에선 안된다는 --rit.base() 해 보았지만, MSVC2005 에선 잘된다. 그래도 컴파일 특성이 다를 수 있으니 (++rit).base() 로 사용하게 좋을 듯 싶다.^^(내부 iterator 가 const_iterator 가 아닌 iterator로 반환하는것을 확인)
개인적인 생각
base() 호출시 바로 it에 대응하는 것을 벹어 낼수도 있는데 왜 항상 다음것을 벹어 내는가? 그 이유는reverse_iterator의 rend() 과 iterator의 begin() 을 매칭 시키기 위해서다. 이렇게 하는 것은 end() 도 자연스럽게 맞쳐지며, 구현자나 사용자나 보다 쉽게 이용할수 있기 때문이라고 개인적으로 생각 한다.(뭐.. base()가 대응되는게 한칸 뒤라는것을 기억해야 하겠지만.^^)
이것만은 잊지 말자
1. base() 가 뱉어내는 iterator는 reverse_iterator 의 전 원소이다.(이해가 어렵다면,, 위의 코드를 보는게 더 도움이 될듯)
관련링크
http://alones.kr/blog/841 <-- 이것도 같은 설명~
http://ilu8318.egloos.com/797949 <-- 이것도 같은 설명
그림으로 표현된 reverse_iterator 와 iterator의 차이
개인적인 생각
base() 호출시 바로 it에 대응하는 것을 벹어 낼수도 있는데 왜 항상 다음것을 벹어 내는가? 그 이유는reverse_iterator의 rend() 과 iterator의 begin() 을 매칭 시키기 위해서다. 이렇게 하는 것은 end() 도 자연스럽게 맞쳐지며, 구현자나 사용자나 보다 쉽게 이용할수 있기 때문이라고 개인적으로 생각 한다.(뭐.. base()가 대응되는게 한칸 뒤라는것을 기억해야 하겠지만.^^)
이것만은 잊지 말자
1. base() 가 뱉어내는 iterator는 reverse_iterator 의 전 원소이다.(이해가 어렵다면,, 위의 코드를 보는게 더 도움이 될듯)
관련링크
http://alones.kr/blog/841 <-- 이것도 같은 설명~
http://ilu8318.egloos.com/797949 <-- 이것도 같은 설명
반응형
'STLTemplate > STL & EffectiveSTL' 카테고리의 다른 글
문자열 string (0) | 2012.12.06 |
---|---|
STL : C++ STL 프로그래밍(6)-해시 맵(Hash Map) (0) | 2012.11.13 |
STL을 이용한 Unicode 텍스트 파일 출력 (0) | 2012.11.04 |
STL 컨테이너 주의할 점 (0) | 2012.11.01 |
이펙티브 STL을 다루는 정리 사이트 (0) | 2012.11.01 |