STL学习笔记——迭代器以及Traits技术

来源:互联网 发布:贵州筏钓网淘宝店 编辑:程序博客网 时间:2024/05/08 15:16
迭代器模式:提供一种方法,使之能够依序访问某个容器中的各个元素,而又无需暴露该容器的内部表述方式。

迭代器是容器和算法之间的胶合剂。


1.如何判断迭代器的类型

    1)通过编译器对函数模版的实参推倒可以解决参数类别的判定,如下

template<class I, class T>  void func_imp1(I Iter, T t)  {    T tmp=t;//由于func_imp1是一个函数模版,一旦被调用,编译器会自动进行参数推倒,导出参数类型为T(改例为int)//...这里为func应该做的工作  }      template<class I>  inline void func(I Iter)  {    func_imp1(Iter,*Iter);  }    int main()  {    int i;func(&i);  }
    2)通过内嵌类型声明解决返回值类型的判定,如下

template<class T>  struct MyIter//迭代器类  {    typedef T value_type; //内嵌类型声明,(类类型可以自己声明,但是内置类型没有办法声明)    T* ptr;MyIter(T* p=0):ptr(p){}T& operator*(){return *ptr;}//.....  };    template<class I>  typename I::value_type func(I Iter)//算法类    !!typename I::value_type为返回值的类型声明  {    return *Iter;  }
   3)通过Traits解决原生指针的返回类型问题
       *不同的容器有不同的专属迭代器,而不同的迭代器具有不同的特性;但是算法的接口确实统一的,
        算法通过Traits技术获取不同的迭代器属性,然后选择正确的流程;
        Traits依靠显式模版特殊化把代码中因类型不同而发生变化的片段提取出来,用统一的接口来包装;
        Traits允许系统在编译的时候根据类型做一些判断,遵循另增一个间接层的宗旨。
       例如:

//泛化版本        template<class I>//I为迭代器类,迭代器类要内嵌类型声明        struct iterator_traits//相当于一个中间层        {  typedef typename I::value_type value_type;};   //特化版本1    template<class I>struct iterator_traits<I*>//迭代器是个原生指针{  typedef I value_type;}      //特化版本2    template<class I>struct iterator_traits< const I*>//迭代器是个原生指针{  typedef I value_type;}//2)的修改版本template<class I>    typename iterator_traits<I>::value_type func(I Iter)//通过iterator_traits类实现接口统一    {      return *Iter;    }
2.迭代器内嵌相应类型
    1)value_type:表示迭代器所指对象的类型
    2)difference_type:表示两个迭代器之间的距离
    3)reference:传递迭代器所指对象的引用
    4)pointer:传递迭代器所指对象的地址

    5)iterator_category(迭代器种类):

            a.Input Iterator:只读,支持p++
            b.Output Iterator:只写,支持p++
            c.Forward Iterator:允许写入型算法在此种迭代器所形成的区间上进行读写操作,支持p++
            d.Bidirectionl Iterator:可双向移动,支持p++,p--
            e.Random Access Iterator:支持p++,p--,p[n],p+n,p-n,p1-p2,p1<p2
           *任何一个迭代器,其类型永远应该落在“该迭代器所隶属的各种类型中,最强化的那个”;
           *STL算法的一个命名规则:以算法所能接收的最低阶迭代器类型,来为其迭代器类型参数命名;template<class InputIterator>
           *迭代器类型之间存在继承关系 InputIterator<-ForwardIterator<-Bidirectionl Iterator<-Random Access Iterator
    注意:任何迭代器都应该提供五个内嵌相应类型,以利于Traits萃取类型。继承STL提供的iterator类可以满足这个要求。
3.STL迭代器关键声明代码

1)//五种迭代器类型(只是用来区分类型,方便实现函数重载)       struct input_iterator_tag{};   struct output_iterator_tag{};   struct forward_iterator_tag : public input_iterator_tag {};   struct bidirectionl_iterator_tag : public forward_iterator_tag {};   struct random_access_iterator_tag : public bidirectionl_iterator_tag {};2)//iterator类,供客户自定义的迭代器类继承   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;   }
3)//iterator_traits类,用来判定类型   //泛化版本   template<class iterator>   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 typename iterator::pointer            pointer;  typedef typename iterator::reference          reference;   }   //特化版本,针对原生指针T*   template<class iterator>   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;   }

4.++、--
    iterator<>& operator ++();//表示前置,++it;
    iterator<>& operator ++(int);//表示后置,it++;

原创粉丝点击