TIL 2024/9/10

Sung Joo Lee·2024년 9월 10일

Iterator(반복자)


  • 컨테이너의 요소에 대해 “추상적”인 접근을 가능하게 하는 기능

    • 추상적 → 컨테이너가 무슨 종류인지, 어떻게 구현되어 있는지 알 필요 없음
    • 예를 들어 vector,array,map,set등은 공통적으로 first()를 사용하여 첫 번째 요소를 호출 할 수 있다.
  • 포인터와 유사하게 사용 가능

  • 대부분 컨테이너는 반복자를 사용해 순환 가능

    • stack, queue는 예외

반복자 선언

#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <list>

int main()
{
	std::vector<int> vec{ 1,2,3 };
	std::set<int> myset{ 1,2,3 };

	std::vector<int>::iterator it1;//반복자 선언
	std::set<int>::iterator it2;//반복자 선언
		
	return 0;
}

반복자의 begin과 end

vector<int> vec{1,2,3};
  • 위의 코드는 내부적으로 어떻게 구성이 되어있는가?

그림과 같이 배열과 비슷하게 구성이 된다. 이때 자동적으로 begin과 end가 생성이 되어 첫 번째 요소와 마지막 요소의 뒤를 가리키게 된다.

set<char> ch{'A','B','C','D'};
  • set은 순서가 없다, indexing으로 접근이 불가함

> 마찬가지로 begin과 end가 자동으로 생성되어 처음과 마지막 요소의 뒤를 가리킨다. >

반복자의 사용

  • for문과 반복자를 사용한 vector 순환
#include <iostream>
#include <vector>

int main()
{
	std::vector<int> vec{ 1,2,3 };

	for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it++)
	{
		std::cout << *it << std::endl;
	}
	

	return 0;
}

근데 사용하기에 너무 길다..! iterator 선언하려면 “std::vector::iterator”를 써야하다니..

그래서 cpp에서는 “auto”라는 키워드를 지원해 준다.

auto 키워드

  • 자동으로 타입을 추정해 주는 키워드
  • 타입이 길어질 경우 사용하면 편리
    • 남용할 경우 코드의 가독성을 떨어지게 한다.
#include <iostream>

int Add(int a, int b)
{
	return a + b;
}

int main(){

	int a = 5;
	auto b = 5;// b is int
	auto c = b; // c is int 

	auto d = Add(2, 3); // d is int

}
💡

즉, 위와 같이 우변의 타입을 보고 컴파일러가 좌변의 타입을 추정해준다.

auto 적용

#include <iostream>
#include <vector>

int main()
{
	std::vector<int> vec{ 1,2,3 };
//std::vector<int>::iterator it = vec.begin();

	auto it = vec.begin();

	return 0;
}

위와 같이 긴 코드를 작성 할 필요없이 간단하게 작성이 가능하다.

반복자의 연산자

  • 반복자는 ‘포인터’와 같기 때문에 포인터의 연산이 가능하다.
#include <iostream>
#include <vector>

int main() {
	std::vector<int> vec{ 1,4,7 };

	auto it = vec.begin();

	it += 2;//연산 사용 가능

	std::cout << *it << std::endl;//iterator를 포인터 개념으로 생각하자

}
  • 다른 컨테이너여도 상관없이 동일하게 사용한다.
#include <iostream>
#include <vector>
#include <set>

int main() {
	std::vector<int> vec{ 1,4,7 };
	std::set<char> mySet{ 'A','B','D' };

	for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it++)
	{
		std::cout << *it << std::endl;
	}

	for (std::set<char>::iterator it2 = mySet.begin(); it2 != mySet.end(); it2++)
	{
		std::cout << *it2 << std::endl;
	}
}

역 반복자

  • 역순으로 동작
  • 일반적인 반복자가 가리키는 방향의 정 반대 방향을 가리킨다.
  • 마지막 요소가 첫 요소가 되는 반복자
  • ++ 및 - - 를 반대 방향으로 생각
#include <iostream>
#include <vector>
#include <set>

int main() {
	std::vector<int> vec{ 1,2,3 };

	for (std::vector<int>::reverse_iterator it = vec.rbegin();it != vec.rend(); ++it)
	{
		std::cout << *it << " "; // 3, 2 , 1 출력
	}

}
profile
개발로그

0개의 댓글