提要
先看一段用迭代器的代码:
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技法,布布扣,bubuko.com
STL源码剖析(二) - 迭代器与traits技法
原文:http://blog.csdn.net/silangquan/article/details/24352549