提要

先看一段用迭代器的代码:

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技法的更多相关文章

  1. STL源代码剖析(一) - 内存分配

    Allocaor allocator 指的是空间配置器,用于分配内存.STL中默认使用SGI STL alloc作为STL的内存分配器,尽管未能符合标准规格,但效率上更好.SGI STL也定义有一个符 ...

  2. STL源代码剖析 读书总结

    <<STL源代码剖析>> 侯捷著 非常早就买了这本书, 一直没看, 如今在实验室师兄代码的时候发现里面使用了大量泛型编程的内容, 让我有了先看看这本书的想法. 看之前我对于泛型 ...

  3. STL源代码剖析——STL算法stl_algo.h

    前言 在前面的博文中剖析了STL的数值算法.基本算法和set集合算法.本文剖析STL其它的算法,比如排序算法.合并算法.查找算法等等.在剖析的时候.会针对函数给出一些样例说明函数的使用.源代码出自SG ...

  4. STL源代码剖析——基本算法stl_algobase.h

    前言 在STL中.算法是常常被使用的,算法在整个STL中起到很关键的数据.本节介绍的是一些基本算法,包括equal.fill.fill_n,iter_swap.lexicographical_comp ...

  5. STL源代码剖析——STL算法之set集合算法

    前言 本节介绍set集合的相关算法,各自是并集set_union,差集set_difference,交集set_intersection 和对称差集set_symmetric_difference.这 ...

  6. 《STL源代码剖析》---stl_deque.h阅读笔记(2)

    看完,<STL源代码剖析>---stl_deque.h阅读笔记(1)后.再看代码: G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_deque. ...

  7. 带你深入理解STL之迭代器和Traits技法

    在开始讲迭代器之前,先列举几个例子,由浅入深的来理解一下为什么要设计迭代器. //对于int类的求和函数 int sum(int *a , int n) { int sum = 0 ; for (in ...

  8. STL 源代码剖析 算法 stl_algo.h -- search

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search --------------------------------------- ...

  9. STL源代码剖析 容器 stl_hashtable.h

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie hashtable ------------------------------------ ...

随机推荐

  1. 如何手工搭建本地Yum仓库

    如何手工搭建本地Yum仓库(重点推荐)  https://www.linuxidc.com/Linux/2016-09/135480.htm CentOS7.2 创建本地YUM源和局域网YUM源: h ...

  2. 创建对象——单例(Singleton)模式

      单例(Singleton)模式:   保证一个类在系统里只能有一个对象被实例化.   如:缓存池.数据库连接池.线程池.一些应用服务实例等.   难点:在多线程环境中,保证实例的唯一性.     ...

  3. C++(Typedef声明)

    typedef 声明: 使用 typedef 为一个已有的类型取一个新的名字.下面是使用 typedef 定义一个新类型的语法: typedef type newname; 例如,下面的语句会告诉编译 ...

  4. jmeter元件的作用域和顺序

    jmeter是一个开源的性能测试工具,它可以通过鼠标拖拽来随意改变元件之间的顺序以及元件的父子关系,那么随着它们的顺序和所在的域不同,它们在执行的时候,也会有很多不同. jmeter的test pla ...

  5. 一天搞定jQuery(三)——使用jQuery完成复选框的全选和全不选

    还记得之前我使用JavaScript来实现复选框的全选和全不选效果吗?如果读者初次翻阅本文,可记得看看教你一天玩转JavaScript(七)——使用JavaScript完成复选框的全选和全不选的效果! ...

  6. Xcode5编译ffmpeg

    命令行安装FFmpeg:git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg(或:到https://github.com/gabriel/ffmpeg ...

  7. 随机数生成工具类(中文姓名,性别,Email,手机号,住址)

    public class RandomValueUtil { public static String base = "abcdefghijklmnopqrstuvwxyz012345678 ...

  8. svn汉化包安装无效的解决办法

    下载svn汉化包要和对应的svn客户端版本对应,否则安装无效, 在安装前要想将svn安装目录下的languages目录下的文件全部删除 还有一点要注意的是 汉化包安装要放在svn安装目录下进行安装,它 ...

  9. python字符串方法replace()简介

    今天写replace方法的时候的代码如下: message = "I really like dogs" message.replace('dog','cat') print(me ...

  10. atCoder Ants on a Circle(又是蚂蚁问题。。。)

    atCoder Ants on a Circle(又是蚂蚁问题...) 传送门 题意:一个圈,蚂蚁在上面以相同的速度和不同的方向走,问t秒后它们各自的位置. 解法:和经典的蚂蚁问题一致,把相撞的情况看 ...