STL源代码剖析(二) - 迭代器与traits技法
提要
先看一段用迭代器的代码:
int a[] = {1, 2, 3, 4, 5};
vector<int> v1( a, a+5);
vector<int>::iterator iter = v1.begin( );
for (; iter != v1.end( ); ++iter)
{
cout << *iter << " ";
}
cout<<endl;
STL的中心思想在于:将数据容器(containers)和算法(algorithms)分开,批次独立设计,最后再以一帖胶水将它们撮合在一起。容器和算法的泛型化,从技术角度来看并不困难,C++的classtemplates和function templates可分别达成目标。
迭代器模式定义:提供一种方法,使之能够依序寻訪某个容器所含的各个元素,而又无需暴露该聚合物的内部表达方式。
function template的參数推导机制
在算法中运用迭代器时。可能会用到其对应类型(associative type),即迭代器所指向对象的类别。
但C++仅仅支持sizeof(),并不存在typeof()之说(即使运用RTTI性质中的typeid()获得的也仅仅是类型名称不能用来做变量声明之用)。
为解决此问题。能够利用函数模板(function template)的參数推导(argument deduction)机制。仅将func函数作为一个包装。而把实际的操作放在一个函数func_impl里面完毕。一旦func()函数被调用。编译器就自己主动进行引数推导。自己主动导出类型T。
template <class I, class T>
void fun_impl(I iter, T t){ // 此处该函数利用模板參数推导得知T为*iter类型
T tmp; // 能够声明变量
//...
}; template <class I>
inline void fun(I iter){
fun_impl(iter, *iter); //此处把*iter作为第二个參数传递给fun_impl()
}
int main(int argc, char *argv[])
{
int i;
fun(&i);
return 0;
}
Traits编程技法
traits技法使得泛型算法或者类的实现能够尽可能对模板參数提出小的要求。使用的方法就是建立一个与參数相关的traits类型,把參数对应的细节隐藏当中。
偏特化(Partial Specialization)的意义 - 假设class template拥有一个以上的template參数。我们能够针对当中某个template參数进行特化工作。
traits所扮演的“特性萃取机”角色,萃取各个迭代器的特性,这里所谓的迭代器特性指的是迭代器的对应类型。
通过class template partial specialization的作用。不论是原生指针还是class-type iterators,都能够让外界方便地取得其对应类型。
五种迭代器类型
依据经验,最经常使用到的迭代器对应型别有五种:
(1)value_type:
是指迭代器所指对象的类型,是指STL容器内所存储的数据类型
(2)difference_type:
用来表示两个迭代器之间的距离。因此它也能够用来表示一个容器的最大容量。由于对于连续空间的容器,头尾之间的距离就是其最大容量。
(3)pointer:
(4)reference:
从迭代器所指之物的内容是否同意改变的角度看,迭代器分为不同意改变所指对象的内容constant iterators和mutable iterators.
(5)iterator_category:
S依据移动特性和施行操作,迭代器可分为五种类型:
Input Iterator:这样的迭代器所指对象,不同意外界改变。仅仅读。
Output Iterator:仅仅写。
Forward Iterator:同意“写入型”算法(比如replace())在此种迭代器所形成的区间上进行读写操作。
Bidirectional Iterator:可双向移动。
Random Access Iterator:前四种迭代器都仅仅供应一部分指针算术能力(前三种支持 operator++。第四种再加上 operator--)。第五种则涵盖全部指针算术能力,包含 p+n, p-n, p[n], p1-p2, p1<p2。
总结
设计适当的型别是迭代器的责任,实际适当的迭代器则是容器的责任。算法全然能够独立于容器和迭代器之外自行发展,仅仅要设计时以迭代器为对外接口就能够了。
traits编程技法大量运用于STL实现中,它利用“内嵌类型”的编程技巧与编译器的參数推导功能,增强C++未能提供的关于型别认证方面的能力。弥补C++不为强类型语言的遗憾。
參考
<<STL源代码剖析>> 侯捷译
STL源代码剖析(二) - 迭代器与traits技法的更多相关文章
- STL源代码剖析(一) - 内存分配
Allocaor allocator 指的是空间配置器,用于分配内存.STL中默认使用SGI STL alloc作为STL的内存分配器,尽管未能符合标准规格,但效率上更好.SGI STL也定义有一个符 ...
- STL源代码剖析 读书总结
<<STL源代码剖析>> 侯捷著 非常早就买了这本书, 一直没看, 如今在实验室师兄代码的时候发现里面使用了大量泛型编程的内容, 让我有了先看看这本书的想法. 看之前我对于泛型 ...
- STL源代码剖析——STL算法stl_algo.h
前言 在前面的博文中剖析了STL的数值算法.基本算法和set集合算法.本文剖析STL其它的算法,比如排序算法.合并算法.查找算法等等.在剖析的时候.会针对函数给出一些样例说明函数的使用.源代码出自SG ...
- STL源代码剖析——基本算法stl_algobase.h
前言 在STL中.算法是常常被使用的,算法在整个STL中起到很关键的数据.本节介绍的是一些基本算法,包括equal.fill.fill_n,iter_swap.lexicographical_comp ...
- STL源代码剖析——STL算法之set集合算法
前言 本节介绍set集合的相关算法,各自是并集set_union,差集set_difference,交集set_intersection 和对称差集set_symmetric_difference.这 ...
- 《STL源代码剖析》---stl_deque.h阅读笔记(2)
看完,<STL源代码剖析>---stl_deque.h阅读笔记(1)后.再看代码: G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_deque. ...
- 带你深入理解STL之迭代器和Traits技法
在开始讲迭代器之前,先列举几个例子,由浅入深的来理解一下为什么要设计迭代器. //对于int类的求和函数 int sum(int *a , int n) { int sum = 0 ; for (in ...
- STL 源代码剖析 算法 stl_algo.h -- search
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search --------------------------------------- ...
- STL源代码剖析 容器 stl_hashtable.h
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie hashtable ------------------------------------ ...
随机推荐
- 2105. [NOIP2015] 信息传递
★☆ 输入文件:2015message.in 输出文件:2015message.out 简单对比 时间限制:1 s 内存限制:256 MB [题目描述] 有n个同学(编号为1到n)正在 ...
- Docker在Ubuntu16.04上安装
转自:http://blog.51cto.com/collen7788/2047800 1.添加Docker源 sudo apt-get update 2.增加CA证书 sudo apt-get in ...
- 关于ds添加datarow
有一个dataset DS.如果我想将DS中的某一行复制,得到新的一行,添加到DS中. 可能就会想到:DS.Tables[0].Rows.Add(DS.Tables[0].Rows[i])但是这样程序 ...
- 2014中秋节,用java为QQ游戏美女找茬写辅助
引子 今年中秋闲在家,总要找点事做. 前几天开始学python,很早之前就有计划拿下这门语言了,可惜一直拖到现在……不可否认,我也是个拖沓症患者.在学习python的过程中 ...
- JDBC更新10W级以上数据性能优化
随笔缘由: 系统完成到一定程度,少不了要往数据库中添加大量数据进行性能测试. 我用程序做数据10W条,使用jdbc批更新的API,发现每次只能插入2W多条记录. 一番小小研究,觉得总结一下可能有些意义 ...
- 学习一波redis
作为一名合格的java程序员,做web开发的,除了java,mysql,免不了用到内存数据库redis. 身为一名菜鸟,是时候来一波redis从入门到放弃了,哦不,从入门到精通.. 一.安装部署red ...
- GPC:使用GPC计算intersection容易出现的问题
在使用GPC计算多边形的交的时候,出现问题 //1.2. 另一种方法,判断新的多边形是否和老多边形相交 Poly cross = (PolyDefault) Clip.intersection ...
- 分布式缓存系统Memcached[分享]
个人网站:http://www.51pansou.com memcached视频下载:memcached视频教程 memcached源码下载:memcached源码 Memcached是什么? Mem ...
- CAD控件:梦想CAD控件功能更新 清除图上的所有高亮实体
1,修正得组里面的实体,把删除实体也返回的错误 2,修正代理实体改不了颜色问题. 3,修正捕捉块插入点,有时会跑到很远的位置问题. 4.MxDrawChange类增加ToBlockRefe ...
- java基础——String的常用方法
java中String的常用方法 1.length() 字符串的长度 例:char chars[]={'a','b'.'c'}; String s=new String(chars); i nt le ...