zoukankan      html  css  js  c++  java
  • STL 之 iterator traits 备忘

    //5种迭代器。为了激活重载机制,定义的5个类型。每种迭代器就是一个类型。

    struct input_iterator_tag{};
    struct output_iterator_tag{};
    struct forward_iterator_tag : public input_iterator_tag{};
    struct bidirectional_iterator_tag:public forward_iterator_tag{};
    struct random_access_iterator_tag:public bidirectional_iterator_tag{};


    为了定义自己的迭代器,能够继承自以下的iterator类,避免迭代器型别的没有定义。

    //Base class for iterator class
    template <class Category, class T, class Distance=ptrdiff_t, class Pointer = T*, class Reference =T&>
    struct iterator
    {
        typedef Category iterator_category;
        typedef T value_type;
        typedef Distance difference_type;
        typedef Pointer pointer;
        typedef Reference reference;
    };
    


    iterator_traits类,就是一些typedef。相当于就是将迭代器的最本质的类型忠实的呈现出来。这里值得注意的是,要使得这个迭代器忠实的完毕这项工作,那么各个迭代器的定义就必须定义对应的5个性别。

    value_type difference_type  iterator_category pointer reference .

    template<class Iterator>
    struct iterator_traits
    {
        typedef typename Iterator::category iterator_category;
        typedef typename Iterator::value_type value_type;
        typedef typename Iterator::difference_type difference_type;
        typedef typename Iterator::pointer pointer;
        typedef typename Iterator::reference reference;
    };
    


    然而这对于指针而言是不可行的,由于指针没有结构体,我们无法在当中定义这5个型别,于是针对指针,我们定义了iterator_traits的特化版本号。

    template<class T>
    struct iterator_traits<T*>
    {
        typedef random_access_iterator_tag iterator_category;
        typedef T value_type;
        typedef ptrdiff_t difference_type;
        typedef T* pointer;
        typedef T & reference;
    };
    
    
    template<class T>
    struct iterator_traits<const T*>
    {
        typedef random_access_iterator_tag iterator_category;
        typedef T value_type;
        typedef ptrdiff_t difference_type;
        typedef const T* pointer;
        typedef const T & reference;
        
    };
    

    注:依据指针指向 的内容能否够改变,定义了上述的两种特化版本号。


    以下的函数则是直接返回各个型别的类型:

    template<class Iterator>
    inline typename iterator_traits<Iterator>::iterator_category
    iterator_category(const Iterator&)
    {
      typedef typename iterator_traits<Iterator>::iterator_category category;
      return category(); //random_access_iterator_tag or bidirectional_iterator_tag ...
    }
    
    
    //pointer to the difference_type
    template< class Iterator>
    inline typename iterator_traits<Iterator>::difference_type*
    distance_type (const Iterator &)
    {
      return static_cast<typename iterator_traits<Iterator>::difference_type *>(0);
    }
    
    
    template< class Iterator>
    inline typename iterator_traits<Iterator>::value_type *
    distance_type (const Iterator &)
    {
      return static_cast<typename iterator_traits<Iterator>::value_type* > (0);
    }



    distance函数在上述traits下的实现代码:

    //distance function
    
    
    template<class InputIterator>
    inline iterator_traits<InputIterator>::difference_type
    __distance(InputIterator first, InputIterator last, input_iterator_tag)
    {
      iterator_traits<InputIterator>::difference_type n=0;
      while(first != last)
      {
          ++first;++n;
      }
      return n;
    }
    template<class RandomIterator>
    inline typename iterator_traits<RandomIterator>::difference_type
    __distance(RandomIterator first, RandomIterator last, random_access_iterator_tag)
    {
        return last-first;
    }
    
    
    //user 
    template<class InputIterator>
    inline iterator_traits<InputIterator>::difference_type
    distance(InputIterator first, InputIterator last)
    {
        typedef typename iterator_traits<InputIterator>::iterator_category category;
        return __distance(first,last,category());//category()构造一个暂时对象,进行參数推导,决定重载函数。
    }
    

    參考:STL源代码剖析



  • 相关阅读:
    第十二次作业
    Beta 冲刺(7/7)
    Beta 冲刺(6/7)
    Beta 冲刺(5/7)
    Beta 冲刺(4/7)
    Beta 冲刺(3/7)
    Beta 冲刺(2/7)
    第十次作业
    Beta 冲刺(1/7)
    福大软工 · 最终作业
  • 原文地址:https://www.cnblogs.com/lytwajue/p/7052435.html
Copyright © 2011-2022 走看看