迭代器(iterators)

迭代器

iterators是一种抽象的设计概念,iterator模式在《Design Patterns》一书定义如下:提供一种方法,使之能够依序巡防某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表述方式。
扮演容器与算法之间的桥梁,是所谓的 “泛型指针”,共有五种类型,以及其它衍生变化。从实现的角度来看,迭代器是一种将 operator*,operator->,operator++,operator-- 等指针相关操作予以重载的 class template。 所有 STL 容器都附带有自己专属的迭代器。 native pointer 也是一种迭代器。
STL的中心思想在于:将容器和算法分开,彼此独立设计,最后再以通过迭代器把他们撮合在一起。

迭代器相应类型(associated types)

迭代器所指对象的类型。
利用 function template 的参数推导机制,只能推导出参数的类型,无法推导出函数返回值类型。
迭代器相应类型有五种:
value type
difference type
pointer
reference
iterator category

Traits 编程技术

traits 意为 “特性”,扮演 “特性萃取机” 角色,萃取各个迭代器的特性(相应类型)。
template partial specialization 模板偏特化:针对 template 参数更进一步的条件限制所设计出来的一个特化版本,本身仍然是 template。

tempalte<typename I>
struct iterator_traits
{
    typedef typename I::iterator_category  iterator_category;
    typedef typename I::value_type  value_type;
    typedef typename I::difference_type  difference_type;
    typedef typename I::pointer  pointer;
    typedef typename I::reference  reference;
};

这个所谓的 traits,其意义是,如果 I 定义有自己的 value type,那么通过这个traits 的作用,萃取出来的 value_type就是 I::value_type。
如果迭代器是原生指针,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;
};

迭代器相应类型之一:value type
value type 就是迭代器所指对象的类型。

template <class T>
typename iterator_traits<I>::value_type func(I ite)
{
    return *ite;
}

迭代器相应类型之二:difference type
difference type 用来表示两个迭代器之间的距离。

template <class I, class T>
typename iterator_traits<I>::difference_type cout(I first, I last, const T& value)
{
    typename iterator_traits<I>::difference_type n = 0;
    for (; first != last; ++first)
    {
        ++n;
    }
    return n;
}

迭代器相应类型之三:reference type
在 c++ 中,函数如果要传回左值,都是以 by reference 的方式进行,所以如果 p 是一个迭代器,它的 value type 是 T ,那么*p 应该是T& (即reference type)

迭代器相应类型之四:pointer type

迭代器相应类型之五:iterator_category
输入迭代器 (InputIterator) 是能从所指向元素读取的迭代器 (Iterator) 。输入迭代器 (InputIterator) 仅保证单趟算法的合法性。
输出迭代器 (OutputIterator) 是能写入所指元素的迭代器 (Iterator) 。
向前迭代器 (ForwardIterator) 是一种能从所指向元素读取数据的迭代器 (Iterator) 。
双向迭代器 (BidirectionalIterator) 是能双向移动(即自增与自减)的向前迭代器 (ForwardIterator) 。
随机访问迭代器 (RandomAccessIterator) 是能在常数时间内移动到指向任何元素的双向迭代器 (BidirectionalIterator) 。

std::iterator的保证

为了符合规范,任何迭代器都应该提供五个内嵌相应的类型,以利于traits萃取

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;
};

总结

traits 本质是什么?
多一层间接性,换来灵活性。
iterator_traits 负责萃取迭代器的特性,SGI stl还有__type_traits,它负责萃取类型的特性。

上一篇:python 面向对象专题(21):基础(12)异常


下一篇:File "/bin/yum", line 30 except KeyboardInterrupt, e: SyntaxError: invalid syntax 报错的解决