//5种迭代器。为了激活重载机制,定义的5个类型。每种迭代器就是一个类型。

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类,避免迭代器型别的没有定义。

//Base class for iterator class
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类,就是一些typedef。相当于就是将迭代器的最本质的类型忠实的呈现出来。这里值得注意的是,要使得这个迭代器忠实的完毕这项工作,那么各个迭代器的定义就必须定义对应的5个性别。

value_type difference_type  iterator_category pointer reference .

template<class Iterator>
struct iterator_traits
{
typedef typename 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;
};

然而这对于指针而言是不可行的,由于指针没有结构体,我们无法在当中定义这5个型别,于是针对指针,我们定义了iterator_traits的特化版本号。

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(); //random_access_iterator_tag or bidirectional_iterator_tag ...
} //pointer to the difference_type
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 *
distance_type (const Iterator &)
{
return static_cast<typename iterator_traits<Iterator>::value_type* > (0);
}

distance函数在上述traits下的实现代码:

//distance function

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 RandomIterator>
inline typename iterator_traits<RandomIterator>::difference_type
__distance(RandomIterator first, RandomIterator last, random_access_iterator_tag)
{
return last-first;
} //user
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());//category()构造一个暂时对象,进行參数推导,决定重载函数。

參考:STL源代码剖析

STL 之 iterator traits 备忘的更多相关文章

  1. CPP-STL:STL备忘

    STL备忘(转) 1. string.empty() 不是用来清空字符串,而是判断string是否为空,清空使用string.clear(); 2. string.find等查找的结果要和string ...

  2. STL备忘

    STL备忘 lower_bound 查找第一个大于或等于的数,返回该数字的地址,地址减去首地址即得到数组下标(首地址下标为0) upper_bound 查找第一个大于的数 unique 去重,常用于离 ...

  3. 侯捷STL学习(六)--深入list && Iterator traits

    第十三,四节 深度探索list(上,下) list Gnu2.9源代码实现 注意node代码和图示的位置 实现前闭后开,增加一个空白节点 用的分配器alloc Iterator智能指针,需要知道结点n ...

  4. [g2o]一个备忘

    g2o使用的一个备忘 位姿已知,闭环的帧已知,进行图优化. #include "stdafx.h" #include <vector> #include "P ...

  5. 【STL 源码剖析】浅谈 STL 迭代器与 traits 编程技法

    大家好,我是小贺. 点赞再看,养成习惯 文章每周持续更新,可以微信搜索「herongwei」第一时间阅读和催更,本文 GitHub : https://github.com/rongweihe/Mor ...

  6. GIS部分理论知识备忘随笔

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.高斯克吕格投影带换算 某坐标的经度为112度,其投影的6度带和3度带 ...

  7. python序列,字典备忘

    初识python备忘: 序列:列表,字符串,元组len(d),d[id],del d[id],data in d函数:cmp(x,y),len(seq),list(seq)根据字符串创建列表,max( ...

  8. Vi命令备忘

    备忘 Ctrl+u:向文件首翻半屏: Ctrl+d:向文件尾翻半屏: Ctrl+f:向文件尾翻一屏: Ctrl+b:向文件首翻一屏: Esc:从编辑模式切换到命令模式: ZZ:命令模式下保存当前文件所 ...

  9. ExtJs4常用配置方法备忘

    viewport布局常用属性 new Ext.Viewport({ layout: "border", renderTo: Ext.getBody(), defaults: { b ...

随机推荐

  1. Oracle学习(二):过滤和排序

    1.知识点:能够对比以下的录屏进行阅读 SQL> --字符串大写和小写敏感 SQL> --查询名叫KING的员工信息 SQL> select * 2 from emp 3 where ...

  2. 2015.04.21,外语,读书笔记-《Word Power Made Easy》 12 “如何奉承朋友” SESSION 32

    TEASER PREVIEW 如何描述这些人: 很友好.容易相处的人: 不知疲倦的人: 简单.直率..aboveboard([ə'bʌv'bɔ:d] adv. 光明正大地, 率直地 adj. 光明正大 ...

  3. angularjs1-4 事件指令

    <div ng-app="myApp"> <div ng-controller="firstController"> <div n ...

  4. JavaScript设计模式学习——builder pattern(建造者模式)

    个人理解的应用场景 举个例子,比如想要创建各种类型的车的实例,车的类型有很多种,但创建每种类型车的接口定义可能是一样的,就用到了此模式 相关概念的通俗解释 上述例子中接口的定义叫builder 接口到 ...

  5. vue中插件的使用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. Ubuntu下快速配置Caffe

    Caffe安装 实际上在windows上安装过多次caffe了,无论是BLVC版本的还是Microsoft版本的,ubuntu的按照也进行过,这段时间在自己笔记本上 又折腾了下caffe安装,发现其实 ...

  7. Side effect (computer science)

    In computer science, a function or expression is said to have a side effect if it modifies some stat ...

  8. 激情世界杯,盛夏大放价,CDR 618返场继续嗨

    最近被刷屏应该就是世界杯.世界杯和世界杯了... 进行了到第七天的球迷们,你们还好么 私房钱还剩下多少?上班有没有请假迟到? 哎,中国的小龙虾都去俄罗斯了,就国足队员没去… 满屏而来的不仅是手机朋友圈 ...

  9. day12 字符编码

    计算机基础 启动应用程序 双击QQ 操作系统接受指令然后把该操作转化成0和1发送给CPU CPU接受指令然后把指令发送给内存 内存接受指令把指令发送给硬盘读取数据 QQ在内存中运行 写文本的流程 在记 ...

  10. 三、Git 分支

    使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线.有人把 Git 的分支模型称为它的`‘必杀技特性’',也正因为这一特性,使得 Git 从众多版本控制系统中脱颖而出. 1.分支简介 ...