//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. Educational Codeforces Round 12 E. Beautiful Subarrays trie求两异或值大于等于k对数

    E. Beautiful Subarrays   One day, ZS the Coder wrote down an array of integers a with elements a1,   ...

  2. ES failed to notify ClusterStateListener java.lang.IllegalStateException: environment is not locked

    ES出现异常: failed to notify ClusterStateListenerjava.lang.IllegalStateException: environment is not loc ...

  3. Android ListView getView()方法重复调用导致position错位

    问题现状:Android ListView getView()方法重复调用导致position错位 解决办法:把ListView布局文件的layout_height属性改为fill_parent或者m ...

  4. scp 命令简明介绍

    安全复制(英语:Secure copy,缩写SCP)是指在本地主机与远程主机或者两台远程主机之间基于Secure Shell(SSH)协议安全地传输电脑文件."SCP"通常指安全复 ...

  5. NYOJ 71 独木舟上的旅行【贪心】

    解题思路:给出船的最大载重量w,和n个人,每只船最多可以乘坐两个人,问怎样坐船使得安排的船只的数量最少.这n个人的体重为a1,a2,a3,---,an-1,an首先将体重按升序排列好,再考虑最重的人, ...

  6. 脚本_求和100以内的正整数.sh

    #!bin/bash#功能:求和100以内的正整数#作者:liusingbon#seq 100 可以快速自动生成 100 个整数sum=0for i in $(seq 100)do    sum=$[ ...

  7. 我用windows live Writer 写个日志试试看

    我用windows live Writer 写个日志试试看. 哈哈 播放幻灯片 全部下载

  8. IOS - 退出程序

    - (void)exitApplication { OAAppDelegate *app = [UIApplication sharedApplication].delegate; UIWindow ...

  9. JS中的异步

    Hello,日常更新的我“浪”回来了!!! JS中有三座高山:异步和单线程.作用域和闭包.原型原型链 今天“浪”的主题是JS中的异步和单线程的问题. 主要从这三个方面入手 一.什么是异步(与同步作比较 ...

  10. BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机+map维护Trie树)

    题目大意:略 由于字符集大,要用map维护Trie树 并不能用AC自动机的Trie图优化,不然内存会炸 所以我用AC自动机暴跳fail水过的 显然根据喵星人建AC自动机是不行的,所以要根据问题建 然而 ...