iterator_traits (반복자 특질)

8861 단어 cppcpp

iterator_traits

  • 반복기에 포함되어야 하는 모든 중요한 형식 정의를 지정하는 데 사용되는 템플릿 도우미 구조체입니다.

구문

struct iterator_traits {
   typedef typename Iterator::iterator_category iterator_category;
   typedef typename Iterator::value_type value_type;
   typedef typename Iterator::difference_type difference_type;
   typedef difference_type distance_type;
   typedef typename Iterator::pointer pointer;
   typedef typename Iterator::reference reference;
   };

알고리즘의 일반화

알고리즘의 일반화라는 것은 어떠한 컨테이너도 그 알고리즘을 사용할 수 있게 만드는 것이다.
이 때, 그 알고리즘은 대상 컨테이너를 순회하기 위해서 컨테이너의 반복자를 사용한다. 보통, 시작을 가리키는 반복자와, 끝을 가리키는 반복자를 사용하고 끝을 가리키는 반복자는 순회에 포함되지 않고 컨테이너의 마지막 요소 다음을 가리킨다.
중요한 사실은 STL이 제공하는 알고리즘이 제공하는 컨테이너 뿐 아니라 기본 배열에서도 사용할 수 있게 c++ 표준이 지정되었다.

  • 특정한 형을 사용하는 알고리즘을 일반화 시켜보면
    template< class IteratorType >
    Sum( IteratorType _first, IteratorType _last )
    {
      ???? sum = *_first++;
    
      while( _first != _last )
          sum += *_first++;
    
      return sum;
    }

컨테이너에서는 포인터(pointer)를 일반화한 반복자(iterator)를 사용하기 때문에 시작을 가리키는 반복자와 끝을 가리키는 반복자를 인수로 받아 각 요소들을 순회하면서 합을 구한다. 그런데 요소들의 (type)을 모르기 때문에 그 합의 타입도 알 수 없다.

  • 반복자가 가리키는 타입을 알려주는 value_type으로 일반화한 함수
    template< class IteratorType >
    typename IteratorType::value_type Sum( IteratorType _first, IteratorType _last )
    {
       typename IteratorType::value_type sum = *_first++;
    
       while( _first != _last )
           sum += *_first++;
    
       return sum;
    }
    컨테이너의 반복자는 value_type이라는 타입을 제공한다. 반복자의 value_type은 반복자가 가리키는 요소의 타입이다. 하지만 컨테이너의 반복자는 value_type을 제공하지만 기존의 포인터는 객체가 아니기 때문에 value_type을 제공하지 않으므로 배열에 대해서는 일반화 되지 않았다.

배열의 포인터로 어떻게 요소의 타입을 알 수 있을까?

템플릿 부분 특수화(partial specialization)

  • 배열의 요소 타입을 알아 내기 위해 템플릿의 부분 특수화를 알아야 한다. STL은 부분 특수화를 통해 iterator_traits를 제공한다.
  • 포인터가 아닐 경우
template<class _iter="">
    struct iterator_traits     
    {   // get traits from iterator _Iter
    typedef typename _Iter::iterator_category iterator_category;
    typedef typename _Iter::value_type value_type;      // <--
    typedef typename _Iter::difference_type difference_type;
    typedef difference_type distance_type;  // retained
    typedef typename _Iter::pointer pointer;
    typedef typename _Iter::reference reference;
    };
  • 포인터일 경우
template<class _ty="">
    struct iterator_traits<_Ty *>
    {   // get traits from pointer
    typedef random_access_iterator_tag iterator_category;
    typedef _Ty value_type;         // <--
    typedef ptrdiff_t difference_type;
    typedef ptrdiff_t distance_type;    // retained
    typedef _Ty *pointer;
    typedef _Ty& reference;
    };

부분 특수화를 이용해 포인터일 경우와 반복자일 경우의 value_type을 다르게 하여 제공한다.

iterator_traits

iterator_traits는 반복자 특질이라고 번역되지만 사실, 반복자와 배열의 포인터를 구분하기 위해 만들어진 것이다.

출처

Microsoft

좋은 웹페이지 즐겨찾기