STL源码剖析:迭代器
准备知识
什么是迭代器?
迭代器是链接容器和算法的桥梁,所有的算法都通过迭代器操作容器中的数据
迭代器是一种智能指针,最重要的操作符重载就是
operator*
,operator->
迭代器的实现需要知道容器的具体细节,因此每一种容器都对应自己特有的迭代器,但是迭代器的接口是一致的
Traits编程技巧
目的:提取出容器中存放的数据类型
核心是使用模板技术,在编译期就确认需要调用的函数
嵌套从属名称:
template <typename T>
class Data
{
typedef T value_type;
}; template <typename T>
class Type
{
// typename T::value_type 就是一个嵌套从属名称,其中的typename不能掉
// 理解模板类型中使用模板类型
typedef typename T::value_type value_type;
}; int main()
{
Type<Data<int>>::value_type a(); // a()表示一个类型为int的变量
}
占位参数实现函数重载
占位参数是函数参数,只是这种参数只有参数类型,没有参数名
占位参数同样属于参数列表,可以实现重载
// int是占位参数
void print(int)
{
cout << "void print(int)" << endl;
} void print()
{
cout << "void print()" << endl;
} int main()
{
print(); // 调用void print(int)
print(); // 调用void print()
}
源码
常用的迭代器相应类型
一般在迭代器中常用的容器类型一共5种
template <class I>
struct iterator_traits
{
typedef typename I::iterator_category iterator_category;
typedef typename I::value_type value_type;
typedef typename I::difference_type difference_type;
typedef typename I::pointer pointer;
typedef typename I::reference reference
}; /*
value_type:迭代器所指数据类型
difference_type:表示两个迭代器之间距离的类型
reference:数据内容本身类型
pointer:与reference对应的指针类型
iterator_category:
Input Iterator:只读
Output Iterator:只写
Forward Iterator:可读可写,只能前进,每次前进一个单位
Bidirectional Iterator:可读可写,双向移动,每次移动一个单位
Random Access Iterator:可读可写,双向移动,每次移动多个单位
*/
- 由于原生的指针类型并没有提供者5种类型的定义,因此进行特化处理
// 实现原生指针的类型提取
template <class T>
struct iterator_traits<T*>
{
...
typedef T* pointer;
typedef T& reference;
}; // 实现const指针的类型提取,去掉const属性,因为会通过迭代器操作容器中的数据
template <class T>
struct iterator_traits<const T*>
{
...
typedef const T* pointer;
typedef const T& reference;
};
- 5种iterator_category的类型定义,都只是类型定义,没有任何成员
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完整代码
迭代器类型相关代码
// 五种迭代器类型
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 {}; // 定义一个基础类,提供迭代器需要的类型定义,编译继承实现,防止遗漏
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;
}; // 类型提取
template <class Iterator>
struct iterator_traits {
typedef typename Iterator::iterator_category iterator_category;
typedef typename Iterator::value_type
typedef typename Iterator::difference_type
typedef typename Iterator::pointer
typedef typename Iterator::reference
}; // 针对原生指针的特化处理
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;
}; // 针对const指针的特化处理
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;
}; // 该函数非常方便的提取某个迭代器的类型iterator_category
template <class Iterator>
inline typename iterator_traits<Iterator>::iterator_category iterator_category(const Iterator&)
{
typedef typename iterator_traits<Iterator>::iterator_category category;
return category();
} // 该函数非常方便的提取某个迭代器的类型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*>();
} // 该函数非常方便的提取某个迭代器的类型value_type
template <class Iterator>
inline typename iterator_traits<Iterator>::value_type* value_type(const Iterator&)
{
return static_cast<typename iterator_traits<Iterator>::value_type*>();
}
- advance函数
// 迭代器前进
template <class InputIterator, class Distance>
inline void advance(InputIterator& i, Distance n)
{
__advance(i, n, iterator_category(i));
} // radom迭代器前进
template <class RandomAccessIterator, class Distance>
inline void __advance(RandomAccessIterator& i, Distance n, random_access_iterator_tag)
{
i += n;
} // bidirectional迭代器前进
template <class BidirectionalIterator, class Distance>
inline void __advance(BidirectionalIterator& i, Distance n, bidirectional_iterator_tag)
{
if (n >= )
while (n--) ++i;
else
while (n++) --i;
} // input迭代器前进
template <class InputIterator, class Distance>
inline void __advance(InputIterator& i, Distance n, input_iterator_tag)
{
while (n--) ++i;
}
- distance函数
// 计算迭代器之间的距离
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());
} // 计算random迭代器之间的距离
template <class RandomAccessIterator>
inline iterator_traits<RandomAccessIterator>::difference_type __distance(RandomAccessIterator first, RandomAccessIterator last,
random_access_iterator_tag)
{
return last - first;
} // 计算Input迭代器的距离
template <class InputIterator>
inline iterator_traits<InputIterator>::difference_type __distance(InputIterator first, InputIterator last, input_iterator_tag)
{
iterator_traits<InputIterator>::difference_type n = ;
while (first != last)
{
++first;
++n;
}
return n;
}
- __type_traits技术
不属于标准的STL,属于SGI STL的私有代码
技术和iterator_traits技术相同,只是定义的类型不同,作用场合不同
如POD就是__type_traits中定义的一种类型
部分代码如下:
struct __true_type { };
struct __false_type { }; template <class type>
struct __type_traits
{
typedef __true_type this_dummy_member_must_be_first;
typedef __false_type has_trivial_default_constructor;
typedef __false_type has_trivial_copy_constructor;
typedef __false_type has_trivial_assignment_operator;
typedef __false_type has_trivial_destructor;
typedef __false_type is_POD_type; // 是否是POD类型
}; __STL_TEMPLATE_NULL struct __type_traits<char> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<signed char>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<unsigned char>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<short>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
}; // ... 每种基本类型都有定义 // 对原生的指针类型进行定义
template <class T>
struct __type_traits<T*>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
STL源码剖析:迭代器的更多相关文章
- STL源码剖析 迭代器(iterator)概念与编程技法(三)
1 STL迭代器原理 1.1 迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型,STL设计的精髓在于,把容器(Containers)和算法(Algorithms)分开,而迭代器(i ...
- STL源码剖析--迭代器(转)
一.为什么需要traits编程技术 前面说了很多关于traits的光荣事迹,但是却一直没有介绍traits究竟是个什么东西,究竟是用来干什么的?traits在英文解释中就是特性,下面将会引入trait ...
- STL源码剖析(迭代器)
在STL中,容器跟算法是分开设计的,算法是通过迭代器来对容器进行操作的. 在算法运用迭代器的时候,可能会用到其相应的型别,例如返回值为容器中元素的型别,又或者说根据迭代器的类型来选择更好的算法等等. ...
- 【STL 源码剖析】浅谈 STL 迭代器与 traits 编程技法
大家好,我是小贺. 点赞再看,养成习惯 文章每周持续更新,可以微信搜索「herongwei」第一时间阅读和催更,本文 GitHub : https://github.com/rongweihe/Mor ...
- STL"源码"剖析-重点知识总结
STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...
- 【转载】STL"源码"剖析-重点知识总结
原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点 ...
- (原创滴~)STL源码剖析读书总结1——GP和内存管理
读完侯捷先生的<STL源码剖析>,感觉真如他本人所说的"庖丁解牛,恢恢乎游刃有余",STL底层的实现一览无余,给人一种自己的C++水平又提升了一个level的幻觉,呵呵 ...
- STL源码剖析读书笔记之vector
STL源码剖析读书笔记之vector 1.vector概述 vector是一种序列式容器,我的理解是vector就像数组.但是数组有一个很大的问题就是当我们分配 一个一定大小的数组的时候,起初也许我们 ...
- STL"源码"剖析
STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略 ...
- 《STL源码剖析》相关面试题总结
原文链接:http://www.cnblogs.com/raichen/p/5817158.html 一.STL简介 STL提供六大组件,彼此可以组合套用: 容器容器就是各种数据结构,我就不多说,看看 ...
随机推荐
- centos 6.5 nat方式上网络设置
1 前提虚拟机采用nat的方式和主机进行通信,这个时候再电脑上会模拟一个vmnet8网卡,如果是host-only对应的是vmnet1,配置一样 vmnet8的虚拟网卡,虚拟机通过vmnet8和主机之 ...
- Win8.1安装配置64位Oracle Database 11g的详细图文步骤记录
在开始Oracle数据安装之前建议:1.关闭本机的病毒防火墙.2.断开互联网. 这样可以避免解压缩丢失文件和安装失败. Step1 Oracle官网下载好Windows系统64位的安装包,下载速度慢的 ...
- 入门大数据---ClouderaManager和CDH是什么?
1.CDH概述 CDH(Cloudra's Distribution Apache Of Hadoop)是Apache Hadoop和相关项目的最完整,经过测试和最流行的发行版.CDH提供Hadoop ...
- python脚本中调用其他脚本
如果只关注脚本中调用他脚本直接看代码30行 PS:该脚本功能有:自动清理目录,创建目录,自动运行脚本,以此提升工作效率 import numpy as np import os from shutil ...
- Python实用笔记 (14)函数式编程——匿名函数
当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便. 在Python中,对匿名函数提供了有限支持.还是以map()函数为例,计算f(x)=x2时,除了定义一个f(x)的函数外, ...
- 08 . Kubernetes之 ingress及Ingress Controller
Ingress简介 ingress是什么? 上篇文章介绍service时有说了暴露了service的三种方式ClusterIP.NodePort与LoadBalance,这几种方式都是在service ...
- WSL配置高翔vslam环境配置流水账
1 安装参考博文链接:https://www.cnblogs.com/dalaska/p/12802384.html 2 Ubuntu 16.04地址:https://www.microsoft.co ...
- Tomcat的启停脚本源码解析
Tomcat是一款我们平时开发过程中最常用到的Servlet容器.本系列博客会记录Tomcat的整体架构.主要组件.IO线程模型.请求在Tomcat内部的流转过程以及一些Tomcat调优的相关知识. ...
- java 中Object类中toString()的使用
1. 当我们输出一个对象的引用时,实际上就是调用当前对象的toString() 2. Object类中toString()的定义: public String toString() { return ...
- HDU 5961 传递 题解
题目 我们称一个有向图G是 传递的,当且仅当对任意三个不同的顶点a,,若G中有 一条边从a到b且有一条边从b到c ,则G中同样有一条边从a到c. 我们称图G是一个 竞赛图,当且仅当它是一个有向图且它的 ...