您的位置:首页 > 大数据 > 人工智能

STL源码解析(2) -- 迭代器iterator与traits

2017-09-23 17:07 495 查看
迭代器(Iterator)模式,又叫做游标(Cursor)模式。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。

STL的核心思想在于将数据容器和算法解耦,使得容器和算法有很好的泛型能力,而iterator则在二者之间扮演着胶水的作用,适合二者能够紧密的结合在一起。

STL中iterator类型

根据STL中的分类,iterator包括:

Input Iterator:只能单步向前迭代元素,不允许修改由该类迭代器引用的元素。

Output Iterator:该类迭代器和Input Iterator极其相似,也只能单步向前迭代元素,不同的是该类迭代器对元素只有写的权力。

Forward Iterator:该类迭代器可以在一个正确的区间中进行读写操作,它拥有Input

Iterator的所有特性,和Output Iterator的部分特性,以及单步向前迭代元素的能力。

Bidirectional Iterator:该类迭代器是在Forward Iterator的基础上提供了单步向后迭代元素的能力。

Random Access Iterator:该类迭代器能完成上面所有迭代器的工作,它自己独有的特性就是可以像指针那样进行算术计算,而不是仅仅只有单步向前或向后迭代。

继承关系如下图



iterator在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 {};
/*
*做为实现重载机制的标志符, 仅仅起到区分不同类型iterator的作用
*同时不会占用任何资源
*/
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;
};

struct output_iterator {
typedef output_iterator_tag iterator_category;
typedef void                value_type;
typedef void                difference_type;
typedef void                pointer;
typedef void                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;
ty
4000
pedef 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;
};
/*
*迭代器定义5个型别,任何符合STL规范的iterator都需要定义这5个型别
*/

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

对iterator_traits传入任何一个迭代器都可以很轻松的获取iterator的类型以及各种属性

traits编程技巧大量用于STL的实现当中,利用内嵌型别与编译器的template参数推导功能增强了C++未能提供的关于型别认证方面的能力

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* 或者 const T*的特化模板
*/
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();
}

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*
value_type(const Iterator&) {
return static_cast<typename iterator_traits<Iterator>::value_type*>(0);
}
template <class T, class Distance>
inline input_iterator_tag
iterator_category(const input_iterator<T, Distance>&) {
return input_iterator_tag();
}

inline output_iterator_tag iterator_category(const output_iterator&) {
return output_iterator_tag();
}

template <class T, class Distance>
inline forward_iterator_tag
iterator_category(const forward_iterator<T, Distance>&) {
return forward_iterator_tag();
}

template <class T, class Distance>
inline bidirectional_iterator_tag
iterator_category(const bidirectional_iterator<T, Distance>&) {
return bidirectional_iterator_tag();
}

template <class T, class Distance>
inline random_access_iterator_tag
iterator_category(const random_access_iterator<T, Distance>&) {
return random_access_iterator_tag();
}

template <class T>
inline random_access_iterator_tag iterator_category(const T*) {
return random_access_iterator_tag();
}

template <class T, class Distance>
inline T* value_type(const input_iterator<T, Distance>&) {
return (T*)(0);
}

template <class T, class Distance>
inline T* value_type(const forward_iterator<T, Distance>&) {
return (T*)(0);
}

template <class T, class Distance>
inline T* value_type(const bidirectional_iterator<T, Distance>&) {
return (T*)(0);
}

template <class T, class Distance>
inline T* value_type(const random_access_iterator<T, Distance>&) {
return (T*)(0);
}

template <class T>
inline T* value_type(const T*) { return (T*)(0); }

template <class T, class Distance>
inline Distance* distance_type(const input_iterator<T, Distance>&) {
return (Distance*)(0);
}

template <class T, class Distance>
inline Distance* distance_type(const forward_iterator<T, Distance>&) {
return (Distance*)(0);
}

template <class T, class Distance>
inline Distance*
distance_type(const bidirectional_iterator<T, Distance>&) {
return (Distance*)(0);
}

template <class T, class Distance>
inline Distance*
distance_type(const random_access_iterator<T, Distance>&) {
return (Distance*)(0);
}

template <class T>
inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); }

template <class T, class Distance>
inline Distance* distance_type(const forward_iterator<T, Distance>&) {
return (Distance*)(0);
}

template <class T, class Distance>
inline Distance*
distance_type(const bidirectional_iterator<T, Distance>&) {
return (Distance*)(0);
}

template <class T, class Distance>
inline Distance*
distance_type(const random_access_iterator<T, Distance>&) {
return (Distance*)(0);
}

template <class T>
inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); }

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

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

template <class InputIterator, class Distance>
inline void __advance(InputIterator& 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;
}

template <class InputIterator, class Distance>
inline void advance(InputIterator& i, Distance n) {
__advance(i, n, iterator_category(i));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: