std::copy, std::transform, etc...
대부분의 Dest의 Iterator를 받는 알고리즘들은 그 컨테이너가 공간 요소를 넣기에 충분한 용량 ( capacity ) 를 확보하길 요구한다.
하지만 얼마나 들어올지 모르는 상황에서 컨테이너에 대한 reserve를 할 수 없으니, 반복자 어댑터를 사용하는걸 추천한다.
std::copy, std::transform 같은 알고리즘들은 밑과 같이 작성되어 있다.
template<class InputIt, class OutputIt>
OutputIt copy(InputIt first, InputIt last,
OutputIt d_first)
{
while (first != last) {
*d_first++ = *first++;
}
return d_first;
}
iterator 의 operator= 를 통해 복사 또는 연산을 지원하는데, 반복자 어댑터는 이 iterator의 operator= 를
operator overloading 하여 내부에서 해당 컨테이너의 push 연산을 호출한다.
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); // back_insert_iterator 는 container 내의 push_back을 호출
return (*this);
}
protected:
_Container *container; // pointer to container
};
inserter(), back_inserter(), front_inserter() 는 각각
insert_iterator, back_insert_iterator, front_insert_iterator 를 생성한다.
물론 Container에 맞는 iterator adaptor function을 호출하여야 한다.
inserter()는 내부에서 해당 컨테이너의 insert 함수를 호출한다.
insert_iterator& operator=(typename _Container::value_type&& _Val)
{ // push value into container
iter = container->insert(iter, _STD move(_Val));
++iter;
return (*this);
}
std::list<int> list1{ 1,2,3,4,5 };
std::list<int> examlist1;
std::copy(list1.begin(), list1.end(), std::back_inserter(examlist1));
// 1, 2, 3, 4, 5 -> 내부에선 push_back을 호출함
std::list<int> examlist2;
std::copy(list1.begin(), list1.end(), std::front_inserter(examlist2));
// 5, 4, 3, 2, 1 -> 내부에선 push_front를 호출함
std::list<int> examlist3;
std::copy(list1.begin(), list1.end(), std::inserter(examlist3, examlist3.begin()));
// 1, 2, 3, 4, 5 -> 내무에선 examlist3.insert(list1.begin(), list1.begin() +1... 이 될 것)
물론 inserter 같은 function이 아닌, iterator 자체를 만들어 넣어줄 수도 있다.
std::list<int> examlist4; std::copy(list1.begin(), list1.end(), std::back_insert_iterator<std::list<int>>(examlist4)); std::list<int> examlist5; std::copy(list1.begin(), list1.end(), std::insert_iterator<std::list<int>>(examlist4, examlist4.begin()));
모든 inserter_iterator 들은 nothrow 하다.
'C++ > STL' 카테고리의 다른 글
| STL) 나만의 Allocator( 할당자 ) 만들기 - 1 (0) | 2019.04.16 |
|---|---|
| std::list::splice (0) | 2019.04.12 |
| STL) 분할, 정렬, 힙에 대한 추가 연산들 (stable_*, is_*, is_*_until) (0) | 2019.02.20 |
| STL) 순열(permutation)과 관련된 함수들 (std::next_permutation, std::prev_permutation, std::rotate, std::shuffle) (0) | 2019.02.20 |
| STL) 파티션에 대한 함수들 ( std::partition, std::stable_partition, std::partition_point ) (0) | 2019.02.19 |