transform(), copy() 알고리즘과 같이 연산을 하거나 단순 복사를 하는 알고리즘을 사용할 때, 결과물을 쓰기 위한 반복자(iterator)를 함수 인자로 받는다. = operator로 값을 쓰기 때문에 결과물을 특정 컨테이너 뒤에 삽입하려면 귀찮은 과정을 거쳐야 한다. 이럴 때 쓰라고 만들어 놓은 게 반복자 어댑터이다. 내부 구현을 보면 = operator 를 오버로딩해서 push_back(), push_front(), insert() 를 호출한다.
// 벡터 정의
int arr1[] = { 0, 1, 2, 3, 4 };
int arr2[] = { 5, 6, 7, 8, 9 };
typedef std::vector<int> IntegerVector;
IntegerVector v1(arr1, arr1 + sizeof(arr1) / sizeof(arr1[0]));
IntegerVector v2(arr2, arr2 + sizeof(arr2) / sizeof(arr2[0]));
// v1 벡터의 원소를 v2 벡터에 append한다.
v2.resize(v1.size() + v2.size());
std::copy(v1.begin(), v1.end(), v2.end() - v1.size());
// 콘솔 출력
std::copy(v2.begin(), v2.end(), std::ostream_iterator<int>(std::cout, " "));
반복자 어댑터를 사용 안 하면 resize()와 반복자 연산을 해야 한다.
v2.reserve(v1.size() + v2.size());
std::copy(v1.begin(), v1.end(), std::back_inserter(v2));
reserve()는 원소가 많을 때 여러 번의 메모리 할당을 막으려고 호출한다. 확실히 반복자 어댑터가 간편하고 코드도 더 직관적이다. 이거 땜씨롱 반복자 어댑터를 쓰는 거지.
inserter(),back_inserter(),front_inserter() 는 각각 insert_iterator, back_insert_iterator, front_insert_iterator를 생성하는데, back_insert_iterator의 구현을 살펴보면,
template<class _Container>
class back_insert_iterator : public _Outit
{ // wrap pushes to back of container as output iterator
public:
explicit back_insert_iterator(_Container& _Cont)
: container(&_Cont)
{ // construct with container
}
back_insert_iterator<_Container>& operator=(
typename _Container::const_reference _Val)
{ // push value into container
container->push_back(_Val);
return (*this);
}
protected:
_Container *container; // pointer to container
};
= operator를 오버로딩해서 push_back을 호출한다. preincrement, postincrement, dereference 연산자는 반복자와 같은 동작을 한다.
back_inserter
Visual Studio 2005
Creates an iterator that can insert elements at the back of a specified container.
Parameters
- _Cont
The container into which the back insertion is to be executed.
A back_insert_iterator associated with the container object _Cont.Remarks
Within the Standard Template Library, the argument must refer to one of the three sequence containers that have the member function push_back: deque Class, list Class, or vector Class.
// iterator_back_inserter.cpp // compile with: /EHsc #include <iterator> #include <vector> #include <iostream> int main( ) { using namespace std; int i; vector<int> vec; for ( i = 0 ; i < 3 ; ++i ) { vec.push_back ( i ); } vector <int>::iterator vIter; cout << "The initial vector vec is: ( "; for ( vIter = vec.begin ( ) ; vIter != vec.end ( ); vIter++) cout << *vIter << " "; cout << ")." << endl; // Insertions can be done with template function back_insert_iterator<vector<int> > backiter ( vec ); *backiter = 30; backiter++; *backiter = 40; // Alternatively, insertions can be done with the // back_insert_iterator member function back_inserter ( vec ) = 500; back_inserter ( vec ) = 600; cout << "After the insertions, the vector vec is: ( "; for ( vIter = vec.begin ( ) ; vIter != vec.end ( ); vIter++ ) cout << *vIter << " "; cout << ")." << endl; }
Output
The initial vector vec is: ( 0 1 2 ). After the insertions, the vector vec is: ( 0 1 2 30 40 500 600 ).
반응형
'STLTemplate > STL & EffectiveSTL' 카테고리의 다른 글
STL 무한대, numeric_limits::infinity (0) | 2012.11.01 |
---|---|
lower_bound,upper_bound 예제소스 (0) | 2012.11.01 |
iterator_traits( 반복자 특질 )이란 무엇인가? (0) | 2012.11.01 |
STL 반복자(iterator) (0) | 2012.11.01 |
오토포인터 auto_ptr (0) | 2012.11.01 |