摘要

迭代器是一种行为类似指针的对象,本文介绍iterator与traits的关系,以及对traits内容的补充。包含stl_iterator.h的部分内容,并用c++11对其进行略微改写。

iterator的五种类型

上篇文章已经介绍了这五种类型的特征,它们只是为了激活重载机制而设定,并不需要其他成员。它们的定义如下:

//五种迭代器类型
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的定义:

//自造的iterator最好继承下面的std::iterator
template<typename Category, typename T,
typename Distance = ptrdiff_t,
typename Pointer = T*,
typename Reference = T&>
struct iterator
{
using iterator_category = Category;
using value_type = T;
using difference_type = Distance;
using pointer = Pointer;
using reference = Reference;
}; //萃取机Traits
//萃取出迭代器的特性
template<typename Iterator>
struct iterator_traits
{
using iterator_category = typename Iterator::iterator_category;
using value_type = typename Iterator::value_type;
using difference_type = typename Iterator::difference_type;
using pointer = typename Iterator::pointer;
using reference = typename Iterator::reference;
};
//针对原生指针的片特化版本
template<typename T>
struct iterator_traits<T*>
{
using iterator_category = random_access_iterator_tag;
using value_type = T;
using difference_type = ptrdiff_t;
using pointer = T*;
using reference = T&;
};
//pointer-to-const
template<typename T>
struct iterator_traits<const T*>
{
using iterator_category = random_access_iterator_tag;
using value_type = T;
using difference_type = ptrdiff_t;
using pointer = const T*;
using reference = const T&;
};
//确定某个迭代器类型,并返回该类型的一个迭代器对象,方便进行函数重载
template<typename Iterator>
inline typename iterator_traits<Iterator>::iterator_category
iterator_category(const Iterator&)
{
using category = typename iterator_traits<Iterator>::iterator_category;
return category();
}
//确定某个迭代器的distance type
template<typename Iterator>
inline typename iterator_traits<Iterator>::difference_type*
distance_type(const Iterator&)
{
return static_cast<typename iterator_traits<Iterator>::difference_type*>(nullptr);
}
//确定某个迭代器的value type
template<typename Iterator>
inline typename iterator_traits<Iterator>::value_type*
value_type(const Iterator&)
{
return static_cast<typename iterator_traits<Iterator>::value_type*>(nullptr);
} //整个distance函数的实现,第三个参数只是激活重载机制,无其他用处
template<typename InputIterator>
inline typename iterator_traits<InputIterator>::difference_type
_distance(InputIterator first, InputIterator last, input_iterator_tag)
{
typename iterator_traits<InputIterator>::difference_type n = 0;
while(first != last)
{
++first;
++n;
}
} template<typename RandomAccessIterator>
inline typename iterator_traits<RandomAccessIterator>::difference_type
_distance(RandomAccessIterator first, RandomAccessIterator last, random_access_iterator_tag)
{
return last - first;
}
//对外接口,适应不同类型的迭代器
template<typename InputIterator>
inline typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last)
{
//先利用traits确定迭代器的类型
using category = typename iterator_traits<InputIterator>::iterator_category;
//利用函数重载,第三个参数只是激活重载机制,无其他用处
_distance(first, last, category());
} //整个advance函数的实现,第三个参数只是激活重载机制,无其他用处
template<typename InputerIterator, typename Distance>
inline void _advance(InputerIterator& i, Distance n, input_iterator_tag)
{
while(n--) ++i;
} template<typename BidirectionalIterator, typename Distance>
inline void _advance(BidirectionalIterator i, Distance n, bidirectional_iterator_tag)
{
if(n >= 0)
while(n--) ++i;
else
while(n++) --i;
} template<typename RandomAccessIterator, typename Distacne>
inline void _advance(RandomAccessIterator& i, Distacne n, random_access_iterator_tag)
{
i += n;
} //对外接口,适应不同类型的迭代器
template<typename InputIterator, typename Distance>
inline void advance(InputIterator& i , Distance n)
{
_advance(i, n, iterator_category(i));
} #endif //STL_ITERATOR_H

STL之iterator源码解析的更多相关文章

  1. Java - Iterator源码解析

    java提高篇(三十)-----Iterator 迭代其实我们可以简单地理解为遍历,是一个标准化遍历各类容器里面的所有对象的方法类,它是一个很典型的设计模式.Iterator模式是用于遍历集合类的标准 ...

  2. STL 之 list源码自行实现(iterator)

    (0)文件夹 STL 之 vector源码实现(云算法<< [] = 重载, new delete,throw catch) STLc++中string类的源码 堆(stack) 之 c ...

  3. HashMap 源码解析

    HashMap简介: HashMap在日常的开发中应用的非常之广泛,它是基于Hash表,实现了Map接口,以键值对(key-value)形式进行数据存储,HashMap在数据结构上使用的是数组+链表. ...

  4. Solr DIH JDBC 源码解析

    Solr DIH 源码解析 DataImportHandler.handleRequestBody()中的importer.runCmd(requestParams, sw) if (DataImpo ...

  5. Python2 基本数据结构源码解析

    Python2 基本数据结构源码解析 Contents 0x00. Preface 0x01. PyObject 0x01. PyIntObject 0x02. PyFloatObject 0x04. ...

  6. Java 集合系列13之 WeakHashMap详细介绍(源码解析)和使用示例

    概要 这一章,我们对WeakHashMap进行学习.我们先对WeakHashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用WeakHashMap.第1部分 WeakHashMap介绍 ...

  7. Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例

    概要  前面,我们已经学习了ArrayList,并了解了fail-fast机制.这一章我们接着学习List的实现类——LinkedList.和学习ArrayList一样,接下来呢,我们先对Linked ...

  8. Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例

    概要 上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解Arra ...

  9. Java 集合系列06之 Vector详细介绍(源码解析)和使用示例

    概要 学完ArrayList和LinkedList之后,我们接着学习Vector.学习方式还是和之前一样,先对Vector有个整体认识,然后再学习它的源码:最后再通过实例来学会使用它.第1部分 Vec ...

随机推荐

  1. Maven pom文件中dependency scope用法

    在Maven中依赖的域有:compile.provided.runtime.system.test.import 一.compile(默认) 当依赖的scope为compile的时候,那么当前这个依赖 ...

  2. linux修改镜像

    修改为163yum源-mirrors.163.com 1.首先备份系统自带yum源配置文件/etc/yum.repos.d/CentOS-Base.repo [root@localhost ~]# m ...

  3. PHP:网展cms后台任意文件删除和sql注入

    0x01:目录结构 可以发现Frameword是框架的文件 install安装 public公共文件 uploads储存上传之类的文件 webuser后台文件 Home前台文件 0x02.csrf漏洞 ...

  4. 论文编写工具使用(1)latex软件

    1什么是LaTeX 能用编写程序的模式写论文,将你从格式编辑解脱出来,套用现成的论文程序模板,直接生成.LaTEX(/ˈlɑːtɛx/,常被读作/ˈlɑːtɛk/或/ˈleɪtɛk/),文字形式写作L ...

  5. 不要轻易在java ext 目录放任何三方jar包

    今天在编写一个简单spi 应用demo的时候,在编译时总有一个其他的错误,如下: ERROR Failed to execute goal org.apache.maven.plugins:maven ...

  6. Python 11 提取括号中间的内容

    原文:https://blog.csdn.net/your_answer/article/details/80456550 import re string = 'abe(ac)ad)' p1 = r ...

  7. Java实现PV操作 | 读者与写者(在三种情况下进行讨论)

    注 :本文应结合[天勤笔记]进行学习. 1.读者优先 设置rmutex信号量来对readcount变量进行互斥访问.mutex信号量对写者与读者进行同步. static syn rmutex=new ...

  8. BZOJ2151/洛谷P1792 题解

    若想要深入学习反悔贪心,传送门. Description: 有 \(n\) 个位置,每个位置有一个价值.有 \(m\) 个树苗,将这些树苗种在这些位置上,相邻位置不能都种.求可以得到的最大值或无解信息 ...

  9. uni-app 事件以及事件绑定

    事件修饰符stop的使用会阻止冒泡,但是同时绑定了一个非冒泡的事件,会导致该元素上的catchEventName失效! prevent可以直接干掉,因为uni-app里没有什么默认事件,比如submi ...

  10. 使用 gitstats 来统计代码

    使用 gitstats 来统计代码 github地址如下 gitstats clone地址 git clone https://github.com/hoxu/gitstats && ...