STL源码剖析—迭代器与traits编程方法
STL的中心思想就是将算法和容器分开,彼此独立设计,最后再以粘合在一起,算法和容器的泛型化,并不是很难,C++的class templates和function templates可以达成目标,但是粘合在一起就是迭代器的事情。
这么一说迭代器就是为了粘合算法和容器的,如果单独设计迭代器,那么这个迭代器就必须知道某个特定容器的内部数据,会暴露太多的信息,这样就规定每一种STL容器都提供有专属迭代器。
迭代器所指对象的型别,称为该迭代器的value_type。所谓value_type,是指迭代器所指对象的型别。任何一个打算与STL算法有完美搭配的class,都应该定义自己的value type内嵌型别。
Difference_type用来表示两个迭代器之间的距离。可以用来表示一个容器的最大容量。迭代器的种类
Pointer是这种类型的指针
Reference是这种类型的引用
Iterator_category是迭代器的类别:
至于迭代器的类别,可以分为五类,inputiterator outputiteratorforwarditerator bidirectional iterator random access iterator 就是根据iteratorcategory来判读一个迭代器是什么类别的,各个迭代器有不同的作用和特性。那么如何判断五中迭代器呢,是根据五个类来判断的。为什么要判断迭代器的类型呢?因为对于不同的迭代器来说,同一个算法的处理不一样。会有效率的区别。所以定义了一个iterator_category来判断迭代器的属于哪一类。然后调用相应的重载函数。
这个时候问题就来了,在STL中的所有容器中,都定义了上述五种迭代器(value_type iteator_catefory…..),那么对于算法而言,就可以通过一种方式来使用容器里的这五种迭代器了(因为所有的算法只需要知道迭代器就可以了,根据迭代器的属性再进行相应的判断),那么如果容器中都实现了这五类迭代器,这么一来算法和容器不久结合在一块了么。
同时为了更方便的使用类中的这五类迭代器,还定义了一个“萃取”的类。
Template<class T>
Structiterator_traits {
Typedeftyepname I::iterator_category iterator_category;
Typedeftyepname I::value_type value_type;
Typedef tyepname I::difference_type difference_type;
Typedef tyepname I::pointer pointer;
Typedef tyepname I::reference reference;
};
同时对于原始指针,又对上面的这个类进行了偏特化。为啥要给原始指针偏特化呢?因为原始指针不是class type.原生指针就是指向内建类型的指针。
也就是说,对于所有的STL容器都自己实现了上面的五种类型,对外外部,使用了一个类(struct iterator_traits)来萃取容器中的这五种定义,算法根据需要来调用这个萃取类,从容器中萃取出自己需要的东西。所以这么一说,迭代器就是算法和容器的粘合剂。这个时候已经知道了迭代器的重要性了。所以,到这里,一定要明白,迭代器是算法和容器粘合的重要内容,怎么粘合的就是上面讲述的内容。
为了符合规范,任何迭代器都应该提供五个内嵌相应型别,以利于traits萃取,否则便是自别于整个STL架构,可能无法与其他STL组件顺序搭配,然后写代码难免疏漏,谁也不能保证不会粗心大意,STL提供了一个iterators class如下,如果每个新设计的迭代器都继承他,就可保证符合STL所需之规范:
Template<class Category,
Class T,
Class distance = ptrdiff_t
Class pointer = T*
Class reference = T&>
Structiterator {
Typedef category_iterator_category;
Typedef T value_type;
Typedef Distance difference_type;
Typedef pointer pointer;
Typedef reference reference;
};
Traits编程技法大量运用于SLT实现中,它利用“内嵌型别“的编程技巧与编译器的template参数推导功能,增强C++未能提供的关于型别认证方面的能力。
最后再通过stl_iterator.h文件中的内容查看iterator源代码的完整代码,就可以看到有五种迭代器类型、自己定义了迭代器类,就是上面的这个类。有一个struct iterator_traits称为萃取,针对原生指针的萃取特化。
总结:突发奇想,到此为止,讲述了空间配置和迭代器这两块内容,
原文地址:http://blog.csdn.net/yusiguyuan/article/details/41807859