[C++STL] 반복자 - X::iterator & X::const_iterator

박남호·2022년 12월 14일
0

STL의 모든 컨테이너는 정방향 반복자 X::iterator와 X::const_iterator를 정의한다. 또한, 역방향 반복자 형식 X::reverse_iterator와 X::const_reverse_iterator를 정의한다.

아래 예제는 iterator와 const_iterator 반복자의 읽기와 쓰기를 위한 예제이다.

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int main(void)
{
	vector<int> v;
	v.push_back(10);
	v.push_back(20);
	v.push_back(30);
	v.push_back(40);
	v.push_back(50);

	vector<int>::iterator begIter = v.begin();
	vector<int>::iterator endIter = v.end();
	cout << "v: ";
	while (endIter != begIter)
	{
		cout << *begIter << ' ';
		++begIter;
	}
	cout << endl;

	vector<int>::const_iterator begConstIter = v.begin();
	vector<int>::const_iterator endConstIter = v.end();
	cout << "v: ";
	while (endConstIter != begConstIter)
	{
		cout << *begConstIter << ' ';
		++begConstIter; // pointer to const data. not a const pointer to data.
	}
	cout << endl;

	vector<int>::iterator iter = v.begin();
	*iter = 100;
	vector<int>::const_iterator constIter = v.begin();
	// *constIter = 100; compile error.

	return 0;
}

iterator iter는 읽기 쓰기가 가능하고 const_iterator는 읽기만 가능하다.

반복자가 가리키는 원소의 위치를 변경하지 않으려면 const 키워드를 사용하여 반복자를 const화 할 수 있다. 아래는 네 경우의 반복 동작을 보여주는 예제이다.

#include <iostream>
#include <vector>

using namespace std;

int main(void)
{
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(40);

    vector<int>::iterator iter = v.begin();
    vector<int>::const_iterator constIter = v.begin();
    const vector<int>::iterator iterConst = v.begin();
    const vector<int>::const_iterator constIterConst = v.begin();

    *iter = 100; // 가리키는 원소 변경 가능
    ++iter; // 반복자 변경 가능

    // *constIter = 100; // 가리키는 원소 변경 불가능
    ++constIter;// 반복자 변경 가능

    *iterConst = 100; // 가리키는 원소 변경 가능
    // ++iterConst; // 반복자 변경 불가능

    // *constIterConst = 100; // 가리키는 원소 변경 불가능
    // ++constIterConst; // 반복자 변경 불가능

    return 0;

vector, deque 컨테이너는 배열 기반 컨테이너로 임의 접근 반복자를 지워하며 list, set, multiset, map, multimap은 양방향 반복자를 지원한다.

아래 예제는 vector와 list 반복자 연산을 비교한 예제이다.

#include <iostream>
#include <vector>
#include <list>

using namespace std;

class Point
{
private:
    int mnX;
    int mnY;

public:
    explicit Point(int nX = 0, int nY = 0)
        : mnX(nX)
        , mnY(nY)
    {}

    void Print() const { cout << mnX << " , " << mnY << endl; }

};

int main(void)
{
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);

    list<int> ls;
    ls.push_back(10);
    ls.push_back(20);
    ls.push_back(30);

    vector<int>::iterator vIter = v.begin();
    list<int>::iterator lsIter = ls.begin();

    cout << "v: " << *vIter << endl;
    cout << "ls: " << *lsIter << endl;

    cout << "v: " << *++vIter << endl;
    cout << "ls: " << *++lsIter << endl;

    cout << "v: " << *--vIter << endl;
    cout << "ls: " << *--lsIter << endl;

    vIter += 2;
    // lsIter += 2; compile error.

    vector<Point> vPoints;
    vPoints.push_back(Point(2, 5));

    list<Point> lsPoints;
    lsPoints.push_back(Point(2, 5));

    vector<Point>::iterator vPointsIter = vPoints.begin();
    vPointsIter->Print();

    list<Point>::iterator lsPointsIter = lsPoints.begin();
    lsPointsIter->Print();

    return 0;

vIter는 임의 접근 반복자이므로 vIter += 2이 가능하지만, lsIter는 양방향 반복자 이므로 lsIter += 2이 불가능하다.
임의 접근 반복자(vector, deque)는 양방향 반복자 기능에 [], +=, -=, +, -, <, >, <=, >= 연산 기능을 더 제공한다.

profile
NamoPark

0개의 댓글