STL源码解析(2) -- 迭代器iterator与traits
2017-09-23 17:07
495 查看
迭代器(Iterator)模式,又叫做游标(Cursor)模式。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。
STL的核心思想在于将数据容器和算法解耦,使得容器和算法有很好的泛型能力,而iterator则在二者之间扮演着胶水的作用,适合二者能够紧密的结合在一起。
Output Iterator:该类迭代器和Input Iterator极其相似,也只能单步向前迭代元素,不同的是该类迭代器对元素只有写的权力。
Forward Iterator:该类迭代器可以在一个正确的区间中进行读写操作,它拥有Input
Iterator的所有特性,和Output Iterator的部分特性,以及单步向前迭代元素的能力。
Bidirectional Iterator:该类迭代器是在Forward Iterator的基础上提供了单步向后迭代元素的能力。
Random Access Iterator:该类迭代器能完成上面所有迭代器的工作,它自己独有的特性就是可以像指针那样进行算术计算,而不是仅仅只有单步向前或向后迭代。
traits编程技巧大量用于STL的实现当中,利用内嵌型别与编译器的template参数推导功能增强了C++未能提供的关于型别认证方面的能力
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)); }
相关文章推荐
- STL源码分析读书笔记--第三章--迭代器(iterator)概念与traits编程技法
- STL源码学习之迭代器iterator 【2013.11.15】
- 范型编程与STL--第二章iterator(迭代器)解析
- STL源码-iterator traits编程技法
- Android设计模式源码解析之迭代器(Iterator)模式
- STL源码学习——迭代器(iterators)与traits编程技法
- STL源码-iterator traits编程技法(续)
- STL源码解析——traits(特性)编程技巧
- STL_源码剖析之三:迭代器与traits
- 【C++ STL应用与实现】19: 迭代器特性-iterator traits
- STL学习笔记之迭代器--iterator(源码剖析)
- stl之再看迭代器iterator(迭代器相应型别和iterator_traits特性以及traits特性萃取)
- STL源码解析之uninitialized_fill_n简单测试-(用到了迭代器萃取和型别萃取)
- STL 源码剖析读书笔记二:迭代器与traits
- STL源码-iterator traits编程技法
- 【STL】迭代器以及“特性萃取机”iterator_traits
- STL源码-iterator traits编程技法(续)
- [STL]源码解析:stack
- STL之迭代器(iterator)
- 《GOF设计模式》—迭代器 (ITERATOR)—Delphi源码示例:基于游标的迭代器