[42서울] containers 일기_week1

tamagoyakii·2023년 2월 8일
0

42seoul

목록 보기
13/19
post-thumbnail

어쩌다 컨테이너...........😿 어디서부터 손대야 할지 감이 안 온다. 이번 주에 살펴본 내용을 정리했다!

STL(Standard Template Library)

STL은 container, iterator, algorithm의 세 가지 라이브러리로 구성되어 있다. 간단하게 한번 살펴보자.

1. Container

컨테이너는 다른 객체(원소)들를 보관하는 하나의 보관소다. STL 컨테이너는 클래스 템플릿 형태로 구현되어 있어 임의의 타입의 원소들을 위한 컨테이너를 만들 수 있다.

컨테이너는 원소들의 메모리를 관리하며, 각각의 원소에 접근할 수 있는 멤버 함수를 제공한다. ft_containers에서 내가 다루게 될 컨테이너는 크게 세 가지 종류로 나뉜다.

1. Sequence containers(순차 컨테이너)

  • array
  • vector
  • deque(double ended queue)
  • forward_list
  • list

2. Container adaptors(컨테이너 어댑터)
기존 컨테이너의 인터페이스를 제한하여 만든, 기능이 제한되거나 변형된 컨테이너를 의미한다. 각각의 기초가 되는 클래스의 인터페이스를 제한하여 특정 형태의 동작만을 수행하도록 한다.

  • stack(LIFO)
  • queue(FIFO)
  • priority_queue

3. Associative containers(연관 컨테이너)

  • set
  • multiset
  • map
  • multimap

더 구체적인 내용은 구현을 시작하면서 차차 포스팅 하도록 하겠다.

2. Iterator

반복자(iterator)란 container 속 임의의 요소를 가리키고 있는 것을 이야기한다. 증감 연산자를 통해 순회할 수 있고, 역참조(*)를 통해 값을 참조할 수 있다.

iterator base class

반복자 클래스를 유도(derive)하는 기초(base) 클래스다. 반복자에서 사용되는 다른 멤버 함수들을 가지고 있지 않으며, 기본 멤버 타입만이 존재한다. 사실 반복자에서 이 멤버 타입을 직접적으로 사용하지는 않지만, iterator_traits 클래스 템플릿에서의 멤버를 선언하여 적절한 형태로 인스턴스화하는 데에 사용된다.

template <class Category, class T, class Distance = ptrdiff_t,
          class Pointer = T*, class Reference = T&>
  struct iterator {
    typedef T         value_type;			// iterator가 가리키는 요소의 타입
    typedef Distance  difference_type;		// 두 iterator의 차이를 나타내는 타입
    typedef Pointer   pointer;				// iterator가 가리키는 요소의 포인터를 나타내는 타입
    typedef Reference reference;			// iterator가 가리키는 요소의 참조자를 나타내는 타입
    typedef Category  iterator_category;	// iterator가 속해 있는 카테고리
  };

iterator_category는 아래의 태그 중 하나이다.

  1. input_iterator_tag
  2. output_iterator_tag
  3. forward_iterator_tag
  4. bidirectional_iterator_tag
  5. random_access_iterator_tag

iterator_traits

iterator_traits에 대해 알기 위해서는 템플릿 부분 특수화의 개념을 알아야 한다.

💡 템플릿 부분 특수화(partial specialization)란?
템플릿에서 특정 타입에 대해서 다른 실행 처리를 하고 싶을 때 템플릿 특수화가 일어난다. 템플릿 완전 특수화는 템플릿의 매개 변수들을 전부 다 특수화하는 반면, 템플릿 부분 특수화는 여러 개의 템플릿 매개 변수 중 일부만 특수화한다.

아래와 같은 템플릿 클래스가 있다고 해보자.

template <typename T1, typename T2>
class MyClass {
	// ...
};

위 템플릿의 인자 중 T2를 정수형으로 받을 때의 경우만 특수화하고 싶다면, 아래와 같이 사용할 수 있다.

template <typename T>
class MyClass<T, int> {
	// ...
};

또, 두 인자 모두 타입의 포인터로 받는 경우에 대한 특수화를 하고 싶다면 아래와 같이 쓰면 된다.

template <typename T1, typename T2>
class MyClass<T1*, T2*> {
	// ...
};

iterator_traits는 반복자 객체의 속성을 정의하는 "반복자 특질"이라고 번역된다. 반복자와 배열의 포인터 및 포인터 상수에 대한 템플릿 특수화라고 생각하면 될 것 같다.

template <class Iterator> class iterator_traits;	// generic definition
template <class T> class iterator_traits<T*>;		// T* specialization
template <class T> class iterator_traits<const T*>;	// const T* specialization

3. Algorithm

컨테이너에 반복자들을 가지고 여러 작업을 수행할 수 있도록 도와주는 라이브러리다. 알고리즘 라이브러리의 함수들은 크게 두 가지로 나뉜다.

template <typename Iter>
void do_something(Iter begin, Iter end);
template <typename Iter, typename Pred>
void do_something(Iter begin, Iter end, Pred pred);

전자의 경우 알고리즘을 수행할 반복자의 시작과 끝만 받지만, 후자의 경우 "특정 조건"을 추가로 받는다. 이를 서술자(predicate)라고 부르며, 여기는 보통 bool 값을 반환하는 함수 객체(functor)가 들어있다.

0개의 댓글