본문 바로가기
C++ STL/Part 02 STL 이해

10장 반복자

by 노오오오오옹 2021. 6. 22.

1. 반복자의 종류

  • 입력 반복자 : 전방향 읽기(istream)
*iter		// 읽기
->		// 멤버 읽기
++		// 전방향 이동
==,!=		// 비교
iterator(iter)	// 반복자
  • 출력 반복자 : 전방향 쓰기(ostream)
*iter = x			// 쓰기
++				// 전방향 이동
iterator(iter)(복사생성지)	// 반복자
  • 순방향 반복자 : 전방향 읽기 + 전방향 쓰기
// 기존 연산자
*iter, ->, ++, ==, !=, iterator(iter)

// 추가된 것
=			// 대입
iterator()(기본 생성자)	// 반복자
  • 양방향 반복자 : 순방향 반복자 + 역방향 읽기 + 역방향 쓰기 (list, set, multiset, map, multimap)
--  // 역방향 이동
  • 임의 접근 반복자 : 양방향 반복자 + 랜덤 읽기 + 랜덤 쓰기 (vector, deque)
[], +=, -=, +, -, <, >, <=, >=

※ 순차열 : 순서있는 원소의 집합 // 구간 : 시작과 끝을 나타내는 반복자의 쌍

vector<int> v = {1,2,3,4,5};

// 구간 [b,e), 순차열 : 1,2,3,4,5

 

2. 반복자와 상수

  • X::iterator, X::const_iterator
vector<int>::iterator iter = v.begin(); // 읽기/쓰기 가능
cout << *iter << endl; // 읽기
*iter = 1; // 쓰기

vector<int>::const_iterator citer = v.begin(); // 읽기만 가능
cout << *citer << endl; // 읽기
// *iter = 1; // 불가능함!

 

  • const X::iterator, const X::const_iterator
const vector<int>::iterator const_iter = v.begin(); // 반복자 변경 불가능
// ++const_iter; // 반복자 변경은 불가능함.

const_iterator const_citer = v.begin(); // 읽기만 가능
// *const_citer = 1; // 불가능함
// ++const_citer; // 반복자 변경은 불가능함.
  • 정리
반복자 쓰기(읽기는 모두 가능) 반복자 변경 가능
X::iterator O O
X::const_iterator X O
const X::iterator O X
const X::const_iteartor  X X

 

3. X::reverse_iterator, X::const_reverse_iterator

모두 역방향 반복자의 형식으로, const에 따라 읽기/쓰기 여부가 정해진다.

vector<int> v = {1,2,3};

for(vector<int>::reverse_iterator riter = v.rbegin(); v != r.rend(); ++iter)
{
    cout << *riter << endl;
}

// 정방향 순차열 : 1,2,3 
// 정방향 시작점 : 1
// 정방향 마지막 : N

// 역방향 순차열 : 3,2,1
// 역방향 시작점 : 3 (N이 아님)
// 역방향 자미막 : ? (1보다 왼족)

정방향과 역방향의 순차열을 동일하게 만들기 위해 한칸씩 땡겼다. 만약 정방향 반복자를 그대로 사용하고 싶다면?

reverse_iterator<vector<int>>::iteartor rbiter(v.end());
reverse_iterator<vector<int>>::iteartor reiter(v.begin());

 

4. 삽입 반복자

순차열에 원소를 넣을 수 있게 하는 반복자 어댑터이다.

덮어쓰기가 아닌 삽입이기  때문에 원소의 개수가 늘어난다.

명칭 생성되는 객체 사용하는 멤버 함수 사용 가능한 컨테이너
inserter() insert_iterator insert() 모든 컨테이너
back_inserter() back_insert_iterator push_back() vector, deque, list : 시퀀스
front_inserter() front_insert_iterator push_front() deque, list
vector<int> v = {1,2,3,4,5};
vector<int> v2;

// copy(b1, e1, insert<T>(v2, b2)) // 덮어쓰기 모드
copy(v1.begin(), v1.end(), insert<vector<int>>(v2, v2.begin());

list<int> lt; // 10->100
list<int> lt2; // 10->100

copy(v.begin(), v.end(), back_insert<list<int>>(lt1));
copy(v.begin(), v.end(), front_insert<list<int>>(lt2));

// back(lt1) : N->10->100->1->2->3->4->5->N
// front(lt2) : N->5->4->3->2->1->10->100->N

 

5. 입/출력 스트림 반복자

  • istream_iterator<T>  : 입력 스트림과 연결, T 형식의 값을 스트림에서 읽을 수 있다.
vector<int>;

// 표준 입력 스트림에서 정수를 받는다, 그리고 v에 저장한다.
copy(istream_iterator<int>(cin, istream_iterator<int>(), back_iterator<int>(v));
  • ostream_iterator<T> : 출력 스트림과 연결, T 형식의 값을 스트림에서 쓸 수 있다.
vector<int> v = {1,2,3,4,5};

copy<v.begin(), v.end(), ostream_iterator<int>(cout));
// 12345 

copy<v.begin(), v.end(), ostream_iteartor<int>(cout, ", ");
// 1, 2, 3, 4, 5,

list<int> lt; // 10, 20, 30

// 화면에 표시(lt와 v, 끝에는 ", "를 붙이고, 두개의 합을)
transform(lt.begin(), lt.end(), v.begin(), v.end(), ostream_iterator<int>(cout, ", "), plus<int>()); 
// 11, 22, 33, 44, 55

 

6. 반복자 특성과 보조 함수

반복자는 입력, 출력, 순방향, 양방향, 임의 접근 반복자가 있다.

각 반복자는 자신만의 특징을 가지고, 특징을 저장한 템플릿 클래스를 반복자의 특성이라고 부른다.

advance()와 distance() 함수로 모든 컨테이너가 (+=, -=, +, -) 연산도 가능하게 할 수 있다.

  • advance(p,n) : p += n 이동
vector<int> v = {1,2,3};
list<int> lt; // 1, 2, 3

vector<int>::iterator viter(v.begin());
list<int>>iterator riter(lt.begin());

advance(viter, 2); // viter += 2
advance(riter, 2); // riter += 2

cout << *viter << ", " << *riter << endl;
// 2, 2
  • n = distance(p1, p2) : n = p2 - p1
list<int> lt; // 1, 2, 3

cout << distance(lt.begin(), lt.end()) << endl; // 원소의 개수 3

// distance의 반환값 : 대부분 unsigned_int, int이지만 반복자에 따라 달라진다.
// difference_type으로 생각하자.


iterator_traits<list<int>::iterator>::differencetype n = distance(lt.begin(), lt.end());
  • iterator_traits의 타입
template<class Iter> 
struct iterator_traits
{
    typedef typename Iter::iterator_category iterator_category;
    typedef typename Iter::value_type value_type;
    typedef typename Iter::difference_type difference_type;
    typedef typename Iter::pointer pointer ;
    typedef typename Iter::reference reference ;
};

'C++ STL > Part 02 STL 이해' 카테고리의 다른 글

12장. string 컨테이너  (0) 2021.06.22
11장. 컨테이너 어댑터  (0) 2021.06.22
9장 STL 함수 객체  (0) 2021.06.22
8장 알고리즘  (0) 2021.06.22
7장 연관 컨테이너  (0) 2021.06.22

댓글