STL 之 iterator traits 备忘
//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 备忘的更多相关文章
- CPP-STL:STL备忘
STL备忘(转) 1. string.empty() 不是用来清空字符串,而是判断string是否为空,清空使用string.clear(); 2. string.find等查找的结果要和string ...
- STL备忘
STL备忘 lower_bound 查找第一个大于或等于的数,返回该数字的地址,地址减去首地址即得到数组下标(首地址下标为0) upper_bound 查找第一个大于的数 unique 去重,常用于离 ...
- 侯捷STL学习(六)--深入list && Iterator traits
第十三,四节 深度探索list(上,下) list Gnu2.9源代码实现 注意node代码和图示的位置 实现前闭后开,增加一个空白节点 用的分配器alloc Iterator智能指针,需要知道结点n ...
- [g2o]一个备忘
g2o使用的一个备忘 位姿已知,闭环的帧已知,进行图优化. #include "stdafx.h" #include <vector> #include "P ...
- 【STL 源码剖析】浅谈 STL 迭代器与 traits 编程技法
大家好,我是小贺. 点赞再看,养成习惯 文章每周持续更新,可以微信搜索「herongwei」第一时间阅读和催更,本文 GitHub : https://github.com/rongweihe/Mor ...
- GIS部分理论知识备忘随笔
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.高斯克吕格投影带换算 某坐标的经度为112度,其投影的6度带和3度带 ...
- python序列,字典备忘
初识python备忘: 序列:列表,字符串,元组len(d),d[id],del d[id],data in d函数:cmp(x,y),len(seq),list(seq)根据字符串创建列表,max( ...
- Vi命令备忘
备忘 Ctrl+u:向文件首翻半屏: Ctrl+d:向文件尾翻半屏: Ctrl+f:向文件尾翻一屏: Ctrl+b:向文件首翻一屏: Esc:从编辑模式切换到命令模式: ZZ:命令模式下保存当前文件所 ...
- ExtJs4常用配置方法备忘
viewport布局常用属性 new Ext.Viewport({ layout: "border", renderTo: Ext.getBody(), defaults: { b ...
随机推荐
- DAC0832、led、蜂鸣器
52控制DAC0832芯片输出电流,让发光二极管D12由灭均匀变到最亮.再有亮变灭.在最亮和最灭的时候蜂鸣器发出报警声,完毕整个周期的时间是控制在5s左右. #include<reg52.h&g ...
- angularjs1-1
<!DOCTYPE html> <html> <body> <header> <meta http-equiv="Content-Typ ...
- h5-爆料view
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAdsAAABeCAIAAADkEim8AAAWAElEQVR4nO2d+1Nb55nHPbMz+1v+g/ ...
- remote debug
https://docs.microsoft.com/en-us/visualstudio/debugger/remote-debugging https://docs.microsoft.com/e ...
- Laravel异常处理
Laravel异常处理 标签(空格分隔): php 自定义异常类 <?php namespace App\Exceptions; use Throwable; use Exception; cl ...
- Memched——C#操作
Memched还是比较简单的,这里把C#的相关操作整理了一下,Mark~ /// <summary> /// 缓存操作类. /// </summary> /// <rem ...
- roboware-studio 使用教程
一.创建工作区 1.1 新建工作区 1.2 选择路径并添加工作区的名字 catkin_ws 二.创建程序包 创建ROS包并添加依赖 my_package roscpp std_msgs 三.添加并编写 ...
- Electron 问题
打包 Mac 桌面程序时报上述错误 E:\research\node\XXX>electron-packager ./ XXX --platform=darwin --arch=x64 --ic ...
- Aspx小记
关闭按钮 protected void Close_Click(object sender, EventArgs e) { //Page.RegisterStartupScript("clo ...
- Sybase to Oracle Golden Gate
Sybase 安装Golden Gate: 下载,然后create subdirs.并且在两端配置好mgr,设置好端口7809 创建golden gate用户ogguser,并且给它授权sa和repl ...