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 ------------------------------------ ...
随机推荐
- LN : leetcode 242 Valid Anagram
lc 242 Valid Anagram 242 Valid Anagram Given two strings s and t, write a function to determine if t ...
- HTML——meta
http://www.cnblogs.com/jr1993/p/4542862.html
- Farseer.net轻量级开源框架 入门篇:修改数据详解
导航 目 录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 添加数据详解 下一篇:Farseer.net轻量级开源框架 入门篇: 删除数据详解 ...
- 设置bootstrap modal模态框的宽度和宽度
(1)修改宽度可以通过修改modal中的modal-dialog这个div宽度实现 <div class="modal-dialog" style="width:6 ...
- Crash (computing)
In computing, a crash (or system crash) occurs when a computer program, such as a software applicati ...
- Exceptions & Errors - 异常与错误
来源于 Ry’s Objective-C Tutorial - RyPress 一个学习Objective-C基础知识的网站. 个人觉得很棒,所以决定抽时间把章节翻译一下. 本人的英语水平有限,有让大 ...
- Functional language 函数
一.什么是函数式语言? 函数式语言一类程序设计语言,是一种非冯·诺伊曼式的程序设计语言.函数式语言主要成分是原始函数.定义函数和函数型.这种语言具有较强的组织数据结构的能力,可以把某一数据 ...
- ThinkPHP---thinkphp模型(M)
(1)配置数据库连接 数据库的连接配置可以在系统配置文件ThinkPHP/Conf/convention.php中找到 /* 数据库设置 */ 'DB_TYPE' => '', // 数据库类型 ...
- Java线程处理
Java线程处理 创建线程 继承Thread类 public class TestThread extends Thread{ public void run(){ System.out.printl ...
- jquery的delegate()方法
delegate() 方法为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数. 使用 delegate() 方法的事件处理程序适用于当前或未来的元素(比如 ...