C++STL迭代器iterator设计

文章目录

  • 前言
  • 迭代器是一种smart pointer
    • auto_ptr
    • 迭代器相应型别associated types
    • traits编程技法
      • 迭代器分类
      • distance
  • std::iterator
  • iterator源代码完整重列
  • SIG STL __type_traits


前言

迭代器是一种抽象的设计概念,现实设计语言中并没有直接对应于这个概念的实物。
iterator模式定义:提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该聚合物的内部表达方式。


迭代器是一种smart pointer

vector::iterator
list::iterator
deque::iterator

auto_ptr

void func()
{
    auto_ptr<string> ps(new string("jjhou));
    cout << *ps << endl;
    cout << ps->size() << endl;
    // 离开前不需要delete
}

迭代器是对象,它需要重载operator*和operator->

// file: 3autoptr.cpp
template<class T>
class auto_ptr 
{
public:
    explicit auto_ptr(T *p = 0):pointee(p) {}
    template<class U> auto_ptr(auto_ptr<U>& rhs): pointee(rhs.release()) {}
    ~auto_ptr() {delete pointee;}

    template<class U>
    auto_ptr<T>& operator=(auto_ptr<U>& rhs)
    {
        if (this != &rhs) reset(rhs.release());
        return *this;
    }
    T& operator*() const {return *pointee;}
    T* operator->() const {return pointee;} /*  ?????????????????????????  */
    T* get() const {return pointee;}
    // ...
private:
    T *pointee;
};

// file: 3mylist.h
template<typename T>
class List
{
private:
    void insert_front(T value);
    void insert_end(T value);
    void display(std::ostream &os = std::cout) const;
    // ...
private:
    ListItem<T>* _end;
    ListItem<T>* _front;
    long _size;
};
template<typename T>
class ListItem
{
public:
    T value() const {return _value;}
    ListItem* next() const {return _next;}
    ...
private:
    T _value;
    ListItem* _next;
};

// file : 3mylist-iter.h
#include "3mylist.h"
template<class Item>
struct ListIter
{
Item* ptr;
ListIter(Item* p = 0):ptr(p) {}

}; 

迭代器相应型别associated types

利用template参数推到机制获得迭代器所指对象的类型

template<class I, class T>
void func_impl(I iter, T t)
{
    T tmp;
    //...
}
template<class I>
inline void func(I iter)
{
    func_impl(iter, *iter);
}
int main()
{
    int i;
    func(&i);
}

traits编程技法

迭代器所指对象的型别称为该迭代器的value type。
模板参数推导机制只能推导参数,无法推导函数的返回值类型。

template<class T>
struct MyIter
{
    typedef T value_type;
    T* ptr;
    MyIter(T* p=0) : ptr(p) { }
    T& operator*() const { return *ptr; }
    // ...
};
template<class I>
//若I不是class则该方法失效,需要特例化该模板
typename iterator_traits<I>::value_type func(I ite)
// typename ::value_type func(I ite)
    { return *ite; }
// ...
MyIter<int> ite(new int(4));
cout << func(ite) << endl;

//特例化

//下面这个class template专门用来“萃取”迭代器的特性,而value type正是其一
template<class I>
struct iterator_traits     //traits意味“特性”
{
    typedef typename I::value_type value_type;
};
template<class T>
struct iterator_traits<T*> //特例化——迭代器是个原生指针
{
    typedef T value_type;
};
//特例化版——当迭代器是个pointer-to-const时,萃取的是T,而非const T
template<class T>
struct iterator_traits<const T*> 
                                  
{
    typedef T value_type;
};
template<>
struct iterator_traits<double>
{
    typedef int value_type;
};

traits

//常用的迭代器相应型别
template<class 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;
    // pointer type
    typedef typename I::pointer            pointer;
    // reference type
    typedef typename I::reference          reference;
};
// iterator_traits必须针对传入的pointer及pointer-to-const,设计特例化版本



// C++内建的ptrdiff_t定义于作为原生指针的difference type
template<class T>
struct iterator_traits<T*>{
    typedef ptrdiff_t defference_type;
    typedef T* pointer;
    typedef T& reference;
};
template<class T>
struct iterator_traits<const T*>{
    typedef ptrdiff_t defference_type;
    typedef const T* pointer;
    typedef const T& reference;
};

Item& operator*() const {return *ptr;}
Item* operator->() const {return ptr;}
Item&为 ListIter的reference type,而Item*为其pointer type

迭代器分类

根据移动特性与施行操作,迭代器被分为五类:

  • input iterator:这种迭代器所指的对象,不允许外界改变。只读
  • output iterator:只写
  • forward iterator:允许“写入型”算法如replace在此中迭代器所形成的区间上进行读写操作
  • bidirectional iterator:可双向移动
  • random access iterator:涵盖所有指针算术能力,p+n, p-n, p[n], p1-p2, p1
// 五个作为编辑用的类型 tag types
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 {};

distance

template<class InputIterator>
inline iterator_traits<InputIterator>::defference_type
__distance(InputIterator first, InputIterator last, input_iterator_tag)
{
    iterator_traits<InputIterator>::defference_type n = 0;
    while (first != last){
        ++first; ++n;
    }
    return n;
}
template<class RandomAccessIterator>
inline iterator_traits<RandomAccessIterator>::difference_type
__distance(RandomAccessIterator first, RandomAccessIterator last, random_access_iterator_tag)
{
    return last - first;
}
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());
}

C++STL迭代器iterator设计_第1张图片

std::iterator

每个新设计的迭代器都应该继承下面的类,以保证与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;
};

新定义的迭代器应该有如下形式

template<class Item>
struct ListIter: public std::iterator<std::forward_iterator_tag, Item>

总结
C++STL迭代器iterator设计_第2张图片

iterator源代码完整重列

SIG STL __type_traits

struct __true_type {};
struct __false_type {};
// 泛化版本
template<class type>
struct __type_traits
{
    typedef __true_type this_dummy_member_must_be_first;
    /*   */
    typedef __false_type  has_trivial_default_constructor;
    typedef __false_type  has_trivial_copy_constructor;
    typedef __false_type  has_trivial_assignment_constructor;
    typedef __false_type  has_trivial_destructor;
    typedef __false_type  is_POD_type;
};
// 自行设计一个__type_traits特例化版本
template<> struct __type_traits<自定义的类>
{
    typedef __true_type  has_trivial_default_constructor;
    typedef __true_type  has_trivial_copy_constructor;
    typedef __true_type  has_trivial_assignment_constructor;
    typedef __true_type  has_trivial_destructor;
    typedef __true_type  is_POD_type;
};

你可能感兴趣的:(c++,STL,迭代器iterator)