STL源码解析(2) -- 迭代器iterator与traits
来源:互联网 发布:3d大型网络手机游戏 编辑:程序博客网 时间:2024/06/18 05:28
迭代器(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; 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;};/* *迭代器定义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_categoryiterator_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_tagiterator_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_tagiterator_category(const forward_iterator<T, Distance>&) { return forward_iterator_tag();}template <class T, class Distance>inline bidirectional_iterator_tagiterator_category(const bidirectional_iterator<T, Distance>&) { return bidirectional_iterator_tag();}template <class T, class Distance>inline random_access_iterator_tagiterator_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_typedistance(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_typedistance(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));}
阅读全文
0 0
- STL源码解析(2) -- 迭代器iterator与traits
- STL源码-iterator traits编程技法
- STL源码-iterator traits编程技法(续)
- STL源码-iterator traits编程技法
- STL源码-iterator traits编程技法(续)
- 【C++ STL应用与实现】19: 迭代器特性-iterator traits
- STL学习笔记--3、迭代器iterator与traits编程
- 迭代器(iterator) 与traits编程
- STL源码剖析笔记四--迭代器与traits技法
- STL源码剖析(二) - 迭代器与traits技法
- STL源码剖析—迭代器与traits编程方法
- STL 源码剖析读书笔记二:迭代器与traits
- STL源码剖析-迭代器概念与traits编程技法
- STL-迭代器与traits技法
- STL 之 iterator traits 备忘
- STL迭代器之迭代器绑定器:Iterator Traits
- 《STL源码剖析》迭代器以及Traits设计
- STL源码解析——traits(特性)编程技巧
- LeetCode(11)——Container With Most Water
- Oracle 过程 Exception
- [Axure]关于微信实现横纵向拖动效果的一些想法
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 题目1 : Visiting Peking University
- 游戏里的人生-扎克斯
- STL源码解析(2) -- 迭代器iterator与traits
- leetcode--Remove Elements
- PAT乙级 1055. 集体照 (25)
- JXL简单操作xls表格文件--写入文件
- 数据结构 — 迷宫问题
- [git]modified: xxx(modified content, untracked content)
- 利用系统相机拍照,摄像,从系统相册中选择图片
- leetcode--Contain Duplicate
- 句柄是什么