[C++] STL 삽입 반복자(insert iterator)
1. Insert iterator
1.1. 컨테이너 요소를 추가하는 방법
- 멤버 함수 ( push_back / emplace_back / insert 등 ) 사용
- 삽입 반복자 (insert iterator)
1.2. 삽입 반복자
#include <iterator>
- 컨테이너에 요소를 추가할 때 사용하는 반복자
- 3가지 종류 - 전방 삽입 / 후방 삽입 / 임의 삽입 제공
1.3. 모양
// back_insert_iterator<컨테이너 클래스 이름> p(컨테이너객체);
back_insert_iterator< list<int> > p(s);
- copy와 같은 STL 알고리즘을 사용해서 컨테이너에 요소를 추가할 수 있음
1.4. 코드로 알아보기
#include <iostream>
#include <list>
#include <iterator>
using namespace std;
int main()
{
list<int> s = { 1,2,3,4,5 };
s.push_back(10);
back_insert_iterator< list<int> > p(s);
*p = 20; // s.push_back(20);
int x[5] = { 100,200,300,400,500};
copy(x, x+5, p);
for (auto& n : s)
cout << n << endl;
}
2. back_inserter 함수
- back_inserter_iterator를 생성해 주는 helper 함수
- 대부분 back+inserter_iterator를 직접 사용하기 보다는 back_inserter()를 사용
- 클래스 템플릿은 반드시 템플릿 인자를 지정해야 하지만 함수 템플릿은 템플릿 인자를 생략할 수 있다 - C++17 이전까지
#include <iostream>
#include <list>
#include <iterator>
using namespace std;
/* 표준에 이미 정의
template<typename T>
back_insert_iterator<T> back_inserter(T& c){
return back_insert_iterator<T>(c);
}
*/
int main()
{
list<int> s = { 1,2,3,4,5 };
int x[5] = { 100,200,300,400,500};
// copy(x, x+5, s.begin()); // 덮어씀
// back_insert_iterator< list<int> > p(s); // 너무 길다
copy(x, x+5, back_inserter(s));
for (auto& n : s)
cout << n << endl;
}
3. Insert iterator 종류
3.1. 종류
- back_insert_iterator (후방 삽입 반복자)
- 생성 함수 : back_inserter
- 내부 구현 : push_back
- front_insert_iterator (전방 삽입 반복자)
- 생성 함수 : front_inserter
- 내부 구현 : push_front
- insert_iterator (임의 삽입 반복자)
- 생성 함수 : inserter
- 내부 구현 : insert
3.2. 주의 사항
- vector는 앞에 삽입할 수 없음 (push_front 멤버함수가 없다)
- 임의 삽입의 경우 생성자 인자가 2개임
insert_iterator< list<int> > p(s, s.begin());
3.3. 전방 삽입과 임의 삽입
- front_insert_iterator를 사용해서 컨테이너에 추가하면 요소의 순서가 반대로 삽입
- insert_iterator를 사용해서 컨테이너의 앞에 삽입하면 요소의 순서대로 삽입
#include <iostream>
#include <list>
#include <iterator>
using namespace std;
int main()
{
list<int> s = { 0,0,0,0,0 };
int x[5] = { 1,2,3,4,5};
// front_insert_iterator< list<int> > p(s);
// insert_iterator< list<int> > p(s, ++s.begin());
// copy(x, x+5, p);
// copy(x, x+5, back_inserter(s)); // 0 0 0 0 1 2 3 4 5
// copy(x, x+5, front_inserter(s)); // 5 4 3 2 1 0 0 0 0 0
copy(x, x+5, inserter(s, ++s.begin())); // 0 1 2 3 4 5 0 0 0 0
for (auto& n : s)
cout << n << endl;
}
3.4. back_insert_iterator 만들어보기
- 모든 반복자는 *로 요소 접근이 가능하고 ++ 연산자로 이동 가능해야 함
- 연산 : ++, *, =
#include <iostream>
#include <list>
#include <iterator>
using namespace std;
template<typename C>
class eback_insert_iterator
{
C* container;
public:
// Member Type
using iterator_category = output_iterator_tag;
using value_type = void;
using pointer = void;
using reference = void;
using difference_type = void;
using container_type = C;
explicit eback_insert_iterator(C& c)
: container(std::addressof(c)) {}
eback_insert_iterator& operator*() { return *this; }
eback_insert_iterator& operator++() { return *this; }
eback_insert_iterator& operator++(int) { return *this; }
eback_insert_iterator& operator=(const typename C::value_type& a)
{
container->push_back(a);
return *this;
}
eback_insert_iterator& operator=(const typename C::value_type&& a)
{
container->push_back(move(a));
return *this;
}
};
int main()
{
list<int> s = { 1, 2 };
eback_insert_iterator< list<int> > p(s);
*p = 30; // ( p.operator*() ).operator=(30)
int x[2] = { 3, 4 };
copy(x, x + 2, p);
for (auto& n : s)
cout << n << endl;
}
참고
codenuri 강석민 강사 강의 내용기반으로 정리한 내용입니다.
코드누리
This is personal diary for study documents.
Please comment if I'm wrong or missing something else 😄.
댓글남기기