iterator_category:简单来说就是提取迭代器类型,为算法选择最有利于其功能的迭代器类型
(迭代器类型有单向,双向,只读,只写,随机 迭代器)。
- traits有能力提取迭代器的种类,我们利用其作为算法的一个参数,这个类别必须是class type,然后就能调用算法的不同形式,以提升效率
//下面我将以advance()算法来描述这个类别
//首先是5个用作标记的型别
struct input_iterator_tag();
struct output_iterator_tag();
struct forward_iterator_tag:public input_iterator_tag{};
struct bidirectional_iterator_tag():public forward_iterator_tag{};
struct random_access_iterator_tag:public bidirectional_iterator_tag();
//下面是advance()算法的具体实现
template<class InuputIterator,class Distance>
inline void __advance(InputIterator& i,Distance n,input_iteratoo_tag){
...
}
template<class ForwardIterator,class Distance>
inline void __advance( ForwardIterator& i,Distance n, forward_iterator_tag){
...
}
template<class BidirectionalIterator,class Distance>
inline void __advance( BidirectionalIterator& i,Distance n, bidirectional_iterator_tag){
...
}
template<class RandomAccesslIterator,class Distance>
inline void __advance( RandomAccesslIterator& i,Distance n, random_access_iterator_tag){
...
}//以上函数的具体实现不同
//每个__advance都只声明类别,不指定参数,只是纯粹用来激活重载机制的。
这时我们需要准备一个上层接口,它只接受两个参数,当它把上述工作给__advance()时,才自行加上第三参数:迭代器类型。然后这个函数必须从迭代器中推导出类型。当然这个工作交traits。
template<class InputIterator,class Distance>
inline void advance(InputIterator &i,Distance n){
__anvance(i,n,iterator_traits<InpurIterator>::iterator_category());
}
为了满足上述行为,traits必须还要增加一个相应的型别:iterator_category;
template<class I>
struct iterator_traits{
...
typedef typename I::iterator_category iterator_category;
};
//另外还有两个偏特化版本,是针对原始指针设计而成,T*,const T*.他们的迭代器类型都是随机访问迭代器。
-
注意:任何一个迭代器都应该落在"该迭代器隶属中"最强化的那一个。例如一个迭代器int*是上面的那5个迭代器类型,但是在程序中我们必须把它当作随机访问迭代器;
STL算法的命名法则:以算法所能接受的最低阶迭代器类型,来为其迭代器类型命名。
-
在上面我所列举的5个类型的型别定义中,后面3个为什么要公有继承前面的两个迭代器类型,为了消除“单纯传递调用的函数”,比如当客端调用distance()并使用Forward iterator时,统统都会调用Input iterator版的那个的__distance()。因为distance()算法里没有Forward iterator 版本。如果没有继承,我们就会在distance()的Forward版本里调用Input版本的。