STL中的迭代器学习

迭代器

什么是迭代器?就是提供一种方法访问容器,而不暴露容器内部的结构,方便使用者访问存取数据,由于STL采用泛型编程,迭代器又是容器和算法相结合的胶水,算法通过迭代器获取容器内部数据进行运算、排序等等,算法和容器不必知道对方结构。

迭代器的类型

五种迭代器类型,分别为只读迭代器、只写迭代器、前向迭代器、双向迭代器、随机访问迭代器

    //定义五种迭代器类型
    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{};

STL还定义了迭代器的基类,所有迭代器的编写,都要继承或者自己在迭代器内部定义这些类型,定义这些类型不会对你迭代器的编写造成任何负担,为STL萃取迭代器的相关类型,以及属性做类型定义。

    //迭代器的基类,重写迭代器应该继承这个
    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;
    };

除此之外,STL还定义五种不同类型迭代器的基类

    //五种迭代器的基类
    template <class T, class Distance>
    struct input_iterator
    {
        typedef input_iterator_tag iterator_category;
        typedef T                   value_type;
        typedef Distance            difference_type;
        typedef T*                  pointer;
        typedef T&                  reference;
    };

    template <class T, class Distance>
    struct output_iterator
    {
        typedef output_iterator_tag iterator_category;
        typedef T                   value_type;
        typedef Distance            difference_type;
        typedef T*                  pointer;
        typedef T&                  reference;
    };

    template <class T, class Distance>
    struct forward_iterator
    {
        typedef forward_iterator_tag iterator_category;
        typedef T                   value_type;
        typedef Distance            difference_type;
        typedef T*                  pointer;
        typedef T&                  reference;
    };

    template <class T, class Distance>
    struct bidirectional_iterator
    {
        typedef bidirectional_iterator_tag iterator_category;
        typedef T                   value_type;
        typedef Distance            difference_type;
        typedef T*                  pointer;
        typedef T&                  reference;
    };

    template <class T, class Distance>
    struct random_access_iterator
    {
        typedef random_access_iterator_tag iterator_category;
        typedef T                   value_type;
        typedef Distance            difference_type;
        typedef T*                  pointer;
        typedef T&                  reference;
    };

谁负责迭代器的编写

答案是容器的编写者,只有容器的编写者才了解其内部结构的构成,在编写迭代器的时候,应该遵循迭代器编写规范,在内部定义相关的类型,分别是

iterator_category  //迭代器类型 
value_type          //迭代器所指类型
difference_type     //迭代器距离类型
pointer             //迭代器所指类型的指针类型
reference;          //所指的引用类型

STL还使用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;
    };

    //对内置指针类型的特例化
    template <class T>
    struct iterator_traits
    {
        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 T*                          pointer;
        typedef T&                          reference;
    };

    //一些函数模板,获取迭代器定义的相关类型
    template <class Iterator>
    inline typename iterator_traits:: iterator_category
        iterator_category(const Iterator&)
    {
            return iterator_traits::iterator_category();
    }

    template <class Iterator>
    inline typename iterator_traits::difference_type*
        distance_type(const Iterator&)
    {
            return static_cast<typename iterator_traits::difference_type*>(0);
    }

    template <class Iterator>
    inline typename iterator_traits::value_type*
        value_type(const Iterator&)
    {
            return static_cast<typename iterator_traits::value_type*>(0);
    }

由于不用类型的迭代器支持不同的访问方式

Input iterator(输入迭代器)
读,不能写
只支持自增运算
Output iterator(输出迭代器) ;
写,不能读
只支持自增运算
Forward iterator(前向迭代器) 
读和写;
只支持自增运算
Bidirectional iterator(双向迭代器) ;
读和写
支持自增和自减运算
Random access iterator(随机访问迭代器) 
读和写;
支持完整的迭代器算术运算

所以对于迭代器距离的计算,有不同的函数

    //根据迭代器类型的不同,迭代器距离的计算也不同
    template <class InputIterator, class Distance>
    inline void __distance(InputIterator __first, InputIterator __last,
        Distance& __n, input_iterator_tag)
    {
        while (__first != __last) 
        { 
            ++__first; 
            ++__n;
        }
    }

    template <class RandomAccessIterator, class Distance>
    inline void __distance(RandomAccessIterator __first,
        RandomAccessIterator __last,
        Distance& __n, random_access_iterator_tag)
    {
        __n += __last - __first;
    }

    template <class InputIterator, class Distance>
    inline void distance(InputIterator __first,
        InputIterator __last, Distance& __n)
    {
        __distance(__first, __last, __n, iterator_category(__first));
    }

    //根据迭代器类型的不同调用不同的迭代器距离函数,提高效率
    template <class InputIterator, class Distance>
    inline void advance(InputIterator& _i, Distance _n)
    {
        _advance(_i, _n, iterator_category(_i));
    }

    template <class InputIter, class Distance>
    inline void __advance(InputIter& __i, Distance __n, input_iterator_tag) {
        while (__n--) 
            ++__i;
    }

    template <class BidirectionalIterator, class _Distance>
    inline void __advance(BidirectionalIterator& __i, _Distance __n,
        bidirectional_iterator_tag) {
        if (__n >= 0)
            while (__n--) 
                ++__i;
        else
            while (__n++) 
                --__i;
    }

    template <class RandomAccessIterator, class Distance>
    inline void __advance(RandomAccessIterator& __i, Distance __n,
        random_access_iterator_tag) {
        __i += __n;
    }

你可能感兴趣的:(C++)