반복자란?
: C++ 라이브러리는 반복자를 제공하는데 이것을 사용하면 라이브러리의 방식대로 자료구조를 액세스 할 수 있다.
따라서 라이브러리가 효과적으로 동작한다는 것을 보장 할 수 있다는 장점이 있다.
즉, 포인터와 상당히 비슷하며, 컨테이너에 저장되어 있는 원소들을 참조할 때 사용한다.
추상적으로 말하자면, 반복자란 컨테이너에 저장되어 있는 모든 원소들을 전체적으로 훑어 나갈 때 사용하는, 일종의 포인터와 비슷한 객체라고 할 수 있다. 알고리즘 마다 각기 다른 방식으로 컨테이너를 훑어가기 때문에, 반복자에도 여러가지 종류가 있게 된다.
영어로 iterate라는 단어는 'to repeat a process, especially as part of a computer program' 이라고 사전적으로 정의되어 있다.
그냥 간단하게 데이터 요소들의 뭉치를 훑기 위해서(iterate 하기 위해서) 사용하는 것이 iterator이다.
1. iterator는 데이터 컬렉션을 iterate over 하기 위해 사용된다.
이 벡터는 일정한 values 값을 모아놓은 컨테이너이다.
다음과 같은 벡터를 생각해 보자.
#include <vector>
#include <iostream>
int main()
{
std::vector<int> values = { 1,2,3,4,5 };
};
이 모아놓은 벡터의 값들 콜렉션(collection) 전체를 훑어서 어떤 작업을 하고 싶을 때 사용하는 것이 iterator인 것.
가장 먼저 이 벡터의 전체 요소를 콘솔에 출력해 주려면 어떻게 해야 할까?
다양한 방법이 있지만 가장 흔한 방법은 for 루프문을 사용하는 것이다.
#include <vector>
#include <iostream>
int main()
{
std::vector<int> values = { 1,2,3,4,5 };
for (int i = 0; i < values.size(); i++)
{
std::cout << values[i] << std::endl;
}
std::cin.get();
};
이렇게 해서 vector values의 데이터 콜렉션 전부를 한 번 훑어줄 수 있다.
다른 방법으로는 다음과 같이 i 같은 변수를 사용하지 않는 방법이다.
ranged base for loop문을 사용하는 것이다. (c++ 11)
#include <vector>
#include <iostream>
int main()
{
for (int value : values)
std::cout << value << std::endl;
std::cin.get();
};
출력해보면 값은 위와 같이 1,2,3,4,5 가 나온다.
RangeBasedForLoop 설명
https://nybot-house.tistory.com/61
이게 어떻게 동작하는 걸까?
기본적으로 Ranged base for loop가 작동할 수 있는 이유는 vector class가 특정한 위치의 iterator를 begin과 end funcion을 통해서 반환해 주기 때문이다. 즉 이 루프문은 다음과 같은 코드의 간략화 버전인 셈이다.
std::vector 는 그 안에 iterator라는 타입을 갖고 있다. (const_iterator 등 4가지 버전이 있는데 여기선 그냥 iterator)
이 iterator를 for문 방식으로 사용해서 std::vector 안의 모든 요소를 iterate 할 수 있다.
#include <vector>
#include <array>
#include <iostream>
int main()
{
std::vector<int> values = { 1,2,3,4,5};
for (std::vector<int>::iterator it = values.begin();
it != values.end(); it++)
{
std::cout << *it << std::endl;
}
std::cin.get();
};
for 문 방식대로 it 에 시작점을 vector values의 첫 값을 begin을 통해 할당해주고, 마지막 지점을 values.end() 를 통해 할당(정확히는 마지막 요소에 하나를 더한 것) 그리고 it++ 를 통해 for문을 만들어 주면 출력값은 같게 나오게 된다.
iterator 값을 호출하기 위해서는 포인터를 역으로 참조해 주어야(*) 호출할 수 있다.
이 iterator를 사용하지 않고 ranged base for loop를 사용하는 경우가 대부분이지만,
iter 중간에 값을 바꿔준다거나 다양한 조작을 하려면 당연히 밑의 방식으로 iterator를 직접 사용해주어야 한다.
또한 벡터의 경우에는 인덱스가 있어서 간단하게 ranged base for loop를 사용할 수 있는 것이지,
인덱스가 없는 경우, 예를 들어 tree, unordered_map과 같은 경우에는 당연히 iterator를 통해서 직접 조작해 주어야 할 것이다.
'C++ 코딩 > C++ 기초개념' 카테고리의 다른 글
C++ Operator Overloading 연산자 오버로딩 (0) | 2022.09.26 |
---|---|
STL 표준 템플릿 라이브러리 (Standard Template Library) (0) | 2022.04.01 |
<C++ 기초> 공용체 union (0) | 2021.03.18 |
<C++ 기초> 구조체 struct, 구조체 응용(*포인터 인수로 사용하기) (0) | 2021.02.24 |
<C++ 기초> 클래스 Class의 기본 - 맴버, 멤버함수, private, public, protect, 캡슐화 (1) | 2021.02.24 |
<C++ 기초> 식과 연산자, 연산자의 종류와 우선순위 (0) | 2021.02.23 |
<C++ 기초> 동적배열, sti vector, 멤버함수 (0) | 2021.02.18 |
<C++ 기초> typedef, 열거형 enum (0) | 2021.02.16 |