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 ------------------------------------ ...
随机推荐
- 创建http对象
package test; import java.net.HttpURLConnection;import java.net.URL; import javax.servlet.http.HttpS ...
- 【C++】Item18. Make interfaces easy to use correctly and hard to use incorrectly
接口容易被正确使用,不易被误用 c++简单工厂模式时,初级实现为ITest* CreateTestOld(), 然后用户负责释放返回的对象.如果忘记释放就会造成memory leak,所以在设计工厂接 ...
- es6数值扩展
1. 二进制和八进制表示法 从 ES5 开始,在严格模式之中,八进制就不再允许使用前缀0表示,ES6 进一步明确,要使用前缀0o表示. ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0 ...
- 树莓派GPIO点亮第一个led
代码如下: 注意:::::此时的GPIO口为18编号口而非GPIO18 import RPi.GPIO as GPIO //引入函数库 import time RPi.GPIO.setmode(GPI ...
- Greenplum开发
Greenplum(GP)采用了MPP架构,基于开源的数据库 PostgreSQL(PG). 1.首先什么是MPP架构? GreenPlum的架构采用了MPP(大规模并行处理).在 MPP 系统中,每 ...
- java死锁问题
一.先从定义上了解一下死锁 二.从代码角度上去解释一下死锁问题 三.上述程序就是出现了死锁,我们来查看一下 1.命令如下 cmd>>jps(查看到了死锁线程所在的类,前面是PID) 2 ...
- ORA-01033:ORACLE initialization or shutdown in process
Oracle遇到问题 :在PL/SQL当输入用户名和密码后 竟然出现标题上错误,我一项目数据库数据库全都没有备份,还有很多很多数据,该不会让我重装数据库吧,想到这个我汗那个流啊. 在网上查了下 看了看 ...
- 网络编程基础_3.APC队列
APC队列 #include <stdio.h> #include <windows.h> // 保存 IO 操作的结果 CHAR Buffer1[] = { }; CHAR ...
- 个人作业Alpha项目测试
这个作业属于哪个课程 软件工程原理 这个作业要求在哪里 作业要求 团队名称 TEAMPANTHER 这个作业的目标 每个同学必须选取非自己所在团队的3个项目进行测试. 在你所测试的项目的Alpha发布 ...
- Redis系列(二)--分布式锁、分布式ID简单实现及思路
分布式锁: Redis可以实现分布式锁,只是讨论Redis的实现思路,而真的实现分布式锁,Zookeeper更加可靠 为什么使用分布式锁: 单机环境下只存在多线程,通过同步操作就可以实现对并发环境的安 ...