1. 迭代器
1.1. 文件名
stl_iterator_base.h
stl_iterator.h
1.2. 背景知识
1.2.1. 泛型编程的几个基本概念
1.2.1.1. concept
concept是一组合法表达式的集合。在这里,表达式是一个抽象的概念,并不仅指C++中的表达式。
或者说,concept就是一组约束条件。
1.2.1.2. module
如果type T满足concept C定义的所有约束条件,那么就说T是C的module。
1.2.1.3. refinement
如果concept C1的所有module都是concept C2的module,那么就说C1是C2的refinement。
1.2.2. Basic Concept
1.2.3. 偏特化 (partial specialization)
偏特化是指对template class或template function作一定程度的特化,特化之后仍然是一个template class或template function。
1.2.4. 迭代器的conecpt
1.2.4.1. Input Iterator
1.2.4.2. Output Iterator
1.2.4.3. Forward Iterator
1.2.4.4. Bidirectional Iterator
1.2.4.5. Random Access Iterator
1.3. 迭代器的associated type
1.3.1. iterator_category
指明迭代器的类型,共有五种类型的迭代器,即:
input iterator
必须可以拷贝和赋值;
如果ite是input iterator,那么*ite ite++ ++ite必须是合法的表达式;
必须可以比较;
output iterator
forward iterator
bidirectional iterator
random access iterator
1.3.2. value_type
1.3.3. difference_type
1.3.4. pointer
1.3.5. reference
1.4. 五种class iterator_tag
都是trival class,没有任何数据成员,也没有任何成员函数。其作用是将iterator划分为五种相应的类别。
1.4.1. class input_iterator_tag
1.4.2. class output_iterator_tag
1.4.3. class forward_iterator_tag
继承自input_iterator_tag
1.4.4. class bidirectional_iterator_tag
继承自forward_iterator_tag
1.4.5. class random_access_iterator_tag
继承自bidirectional_iterator_tag
1.5. 六种class template iterator_base
分别作为五种iterator的基类,以方便定义iterator的associated type,因此自定义的iterator最好继承这些基类,否则必须自己定义iteraotr的五种associated type。
1.5.1. template input_iterator
1.5.1.1. 泛型参数
typename _Tp 指定iterator的value_type
typename _Distence 指定iterator的difference_type
1.5.1.2. 说明
iterator_category 为 input_iterator_tag
pointer 为 _Tp*
reference 为 _Tp&
1.5.2. class ouput_iterator
注意,output_iterator是一个class,而不是一个template,因为其iterator_category为output_iterator_tag, value_type, difference_type,pointer,reference均为void,因此也就不需要泛型化。
1.5.3. template forward_iterator
1.5.3.1. 泛型参数
typename _Tp 指定iterator的value_type
typename _Distence 指定iterator的difference_type
1.5.3.2. 说明
iterator_category 为 forward_iterator_tag
pointer 为 _Tp*
reference 为 _Tp&
1.5.4. template bidirectional_iterator
1.5.4.1. 泛型参数
typename _Tp 指定iterator的value_type
typename _Distence 指定iterator的difference_type
1.5.4.2. 说明
iterator_category 为 bidirectional_iterator_tag
pointer 为 _Tp*
reference 为 _Tp&
1.5.5. template random_access_iterator
1.5.5.1. 泛型参数
typename _Tp 指定iterator的value_type
typename _Distence 指定iterator的difference_type
1.5.5.2. 说明
iterator_category 为 random_access_iterator_tag
pointer 为 _Tp*
reference 为 _Tp&
1.5.6. template iterator
1.5.6.1. 泛型参数
typename _Category 指定iterator_category
typename _Tp 指定value_type
typename _Difference 指定difference_type
typename _Pointer 指定pointer,默认值为 _Tp*
typename _Reference 指定reference,默认值为_Tp&
1.5.6.2. 说明
2.6.1 到2.6.5的五个iterator_base,分别提供了五种类型的iterator_base,但其category不能任意指定,pointer和reference也分别固定为value_type*和value_type&,而iterator提供了最大限度的灵活性,可以任意指定五个associated type。
1.6. template iterator_traits
iterator_traits是一个萃取机,它萃取出iterator的associated type。之所以要引入iterator_traits,是由于C++的原生指针也是一种iterator,但是原生指针本身并不支持五种associated type,所以需要使用iterator_traits萃取原生指针的associated type。iterator_traits是萃取原生指针associated type的方法是使用偏特化。
1.6.1. 泛型参数
typename _Iterator 需要萃取特性的Iterator
1.6.2. 偏特化版本
1.6.2.1. 针对原生指针偏特化
原生指针_Tp*的iterator_category是random_access_iterator_tag,value_type是_Tp,difference_type是ptrdiff_t,pointer是_Tp*,reference是_Tp&。
1.6.2.2. 针对const原生指针偏特化
因为const _Tp*的value_type不应该是const _Tp,而应该是_Tp,因此对const _Tp*提供偏特化。
1.6.3. 兼容老版本STL的三个萃取函数
这三个函数现在已经不在STL标准中了,已经被iterator_traits代替,但是为了与HP STL回溯兼容,保留了这三个函数。
这三个函数的实现方法是:
如果定义了编译器选项__STL_CLASS_PARTIAL_SPECIALIZATION,即编译器支持类的偏特化,那么直接使用iterator_traits来实现。
如果没有定义__STL_CLASS_PARTIAL_SPECIALIZATION,那么无法用iterator_traits来实现,因为iterator_traits本身必须定义了__STL_CLASS_PARTIAL_SPECIALIZATION才会被定义,此时,使用重载的方法来实现,即分别为五种iterator提供重载函数。
1.6.3.1. iterator_category
返回相应的iterator_base。
1.6.3.2. distance_type
返回指向difference_type的指针,因为如果返回difference_type,开销可能比较大。
1.6.3.3. value_type
返回指向value_type的指针,因为如果返回value_type,开销可能比较大。
1.7. 两个辅助函数
1.7.1. distance
计算两个iterator的距离,有两个版本:
如果定义了__STL_CLASS_PARTIAL_SPECIALIZATION,则只需要单纯传入两个iterator,就会返回两个iterator的距离。
如果没有定义__STL_CLASS_PARTIAL_SPECIALIZATION,那么还需要传入一个类型为iterator::difference_type的引用,因为此时编译器无法使用iterator_traits<iteraot>::difference_type来确定返回值的类型,必须要调用者传入。
在实现方法上,对于input_iterator和random_access_iterator,采用不同的实现方法,因为random_access_iterator可以直接相减得到difference_type,而input_iterator则必须遍历[iterator1,iterator)并计数。
1.7.2. advance
使iterator前进某个距离n。
在实现上,分别对input_iteraotr bidirectional_iterator random_access_iterator采用不同的实现方法,因为input_iterator只允许n>=0,而bidirectional_iterator允许n<0,random_access_iterator则允许直接相加,无需步进,效率最高。
1.8. adaptor
1.8.1. template class back_insert_iterator
1.8.1.1. 泛型参数
typename _Container
1.8.1.2. 说明
它是一个output_iterator,使用_Container::value_type为右值向其赋值时会将该值插入到容器尾部。
1.8.2. template function back_inserter
传入一个容器的引用,返回它的back_insert_iterator。
1.8.3. template class front_insert_iterator
1.8.3.1. 泛型参数
typename _Container
1.8.3.2. 说明
它是一个output_iterator,使用_Container::value_type为右值向其赋值时会将该值插入到容器头部。
1.8.4. template function front_inserter
传入一个容器的引用,返回它的front_insert_iterator。
1.8.5. template class insert_iterator
1.8.5.1. 泛型参数
typename _Container
1.8.5.2. 说明
它是一个output_iterator。
初始化时必须指定容器Container和该容器的iteraotr Ite,使用Container的value_type为右值向其赋值时会将该值插入到Ite的前面一个位置,同时Ite下移一位。
1.8.6. template function inserter
传入一个容器的引用,返回它的insert_iterator。
1.8.7. template class reverse_bidirectional_iterator
1.8.7.1. 泛型参数
typename _BidirectionalIterator 反转的iterator type
typename _Tp value_type
typename _Reference reference_type
tynename _Distance difference_type