STL之iterator源码解析
摘要
迭代器是一种行为类似指针的对象,本文介绍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源码解析的更多相关文章
- Java - Iterator源码解析
java提高篇(三十)-----Iterator 迭代其实我们可以简单地理解为遍历,是一个标准化遍历各类容器里面的所有对象的方法类,它是一个很典型的设计模式.Iterator模式是用于遍历集合类的标准 ...
- STL 之 list源码自行实现(iterator)
(0)文件夹 STL 之 vector源码实现(云算法<< [] = 重载, new delete,throw catch) STLc++中string类的源码 堆(stack) 之 c ...
- HashMap 源码解析
HashMap简介: HashMap在日常的开发中应用的非常之广泛,它是基于Hash表,实现了Map接口,以键值对(key-value)形式进行数据存储,HashMap在数据结构上使用的是数组+链表. ...
- Solr DIH JDBC 源码解析
Solr DIH 源码解析 DataImportHandler.handleRequestBody()中的importer.runCmd(requestParams, sw) if (DataImpo ...
- Python2 基本数据结构源码解析
Python2 基本数据结构源码解析 Contents 0x00. Preface 0x01. PyObject 0x01. PyIntObject 0x02. PyFloatObject 0x04. ...
- Java 集合系列13之 WeakHashMap详细介绍(源码解析)和使用示例
概要 这一章,我们对WeakHashMap进行学习.我们先对WeakHashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用WeakHashMap.第1部分 WeakHashMap介绍 ...
- Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例
概要 前面,我们已经学习了ArrayList,并了解了fail-fast机制.这一章我们接着学习List的实现类——LinkedList.和学习ArrayList一样,接下来呢,我们先对Linked ...
- Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
概要 上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解Arra ...
- Java 集合系列06之 Vector详细介绍(源码解析)和使用示例
概要 学完ArrayList和LinkedList之后,我们接着学习Vector.学习方式还是和之前一样,先对Vector有个整体认识,然后再学习它的源码:最后再通过实例来学会使用它.第1部分 Vec ...
随机推荐
- Opencv python图像处理-图像相似度计算
一.相关概念 一般我们人区分谁是谁,给物品分类,都是通过各种特征去辨别的,比如黑长直.大白腿.樱桃唇.瓜子脸.王麻子脸上有麻子,隔壁老王和儿子很像,但是儿子下巴涨了一颗痣和他妈一模一样,让你确定这是你 ...
- 安装Matlab出现弹出DVD1插入DVD2的提示怎么办?
此使,找到DVD1光驱,右键弹出,然后回到dvd2.iso文件右键装载,回到matlab安装页面,对提示框“弹出DVD1插入DVD2”点击确定,安装即可继续进行.
- React 顶层 API
概览 组件 使用 React 组件可以将 UI 拆分为独立且复用的代码片段,每部分都可独立维护.你可以通过子类 React.Component 或 React.PureComponent 来定义 Re ...
- IDEA连接数据库之后,无法自动找到表
在用IDEA连接数据库之后,在查询的时候无法自动关联出表,就如下图的提示所示: 这样看着很不舒服,按照如下设置就可以联想出表了: 点击第一个勾,关联所有: 然后就可以关联到表了
- MongoDB 企业版4.2.2安装
一.下载企业版MongoDB安装RPM包 https://www.mongodb.com/download-center/enterprise 二.安装MogoDB4.2.2企业版 1.安装依赖包 n ...
- ent 基本使用十 数据库迁移
ent 提供了便捷的数据库迁移处理,我们可以直接使用生成的代码进行操作,同时代码也提供了比较全的运行选项 默认迁移处理 我们通过create 进行资源创建,默认是append-only 模式 ,以为着 ...
- [RN] React Native :Error: Cannot find module 'asap/raw'
今天在使用 react-native-dropdownmenus 的时候,安装没问题,但Link的时候 报: Error: Cannot find module 'asap/raw' 朋友们莫慌,一步 ...
- 洛谷 P1144 最短路计数 题解
P1144 最短路计数 题目描述 给出一个\(N\)个顶点\(M\)条边的无向无权图,顶点编号为\(1-N\).问从顶点\(1\)开始,到其他每个点的最短路有几条. 输入格式 第一行包含\(2\)个正 ...
- 第04组alpha冲刺(4/4)
队名:斗地组 组长博客:地址 作业博客:Alpha冲刺(4/4) 各组员情况 林涛(组长) 过去两天完成了哪些任务: 1.分配展示任务 2.收集各个组员的进度 3.写博客 展示GitHub当日代码/文 ...
- uni-app 项目记录
await等候,等待:期待 什么是async.awaitawait 用于等待异步完成通常async.await都是跟随Promise一起使用的 async返回的都是一个Promise对象同时async ...