advanced()对于不同的迭代器类型(类型)有不同的实现方式,类似于重载的概念,(不同的参数对应于不同的实现)。所以,可以使用重载,可以为每个迭代器定义一个类型标志符,使用类型标志符来促成重载。
具体实现如下:
首先必须定义五种迭代器的类型标志符:
//5个迭代器类型
struct input_iterator_tag{};
struct output_iterator_tag{};
struct forward_iterator_tag:public input_iterator_tag,public output_iterator_tag{};
struct bidirectional_iterator_tag:public forward_iterator_tag{};
struct random_access_iterator_tag:public bidirectional_iterator_tag{};
然后对于五个迭代器的具体实现也必须要定义对于该迭代器的类型标志符。
比如说:对于random_access_iterator的定义中,必定有:
class random_access_iterator
{
typedef random_access_iterator_tag iterator_category;
}
然后需要使用迭代器的类型标志符时可以使用iterator_traits,将该迭代器的类型萃取出来
//萃取出迭代器中的各个性质
template<class iterator>
struct iterator_traits {
//不能写成其他的 ,因为要和标准的STL实现无缝链接
typedef typename iterator::value_type value_type;
typedef typename iterator::reference reference;
typedef typename iterator::difference_type difference_type;
typedef typename iterator::pointer pointer;
typedef typename iterator::iterator_category iterator_category;
};
//偏特化针对int*之类的
template<class T>
struct iterator_traits<T*>
{
typedef T value_type;
typedef T& reference;
typedef T* pointer;
typedef ptrdiff_t difference_type;
typedef random_access_iterator_tag iterator_category;
};
//针对const int*
template<class T>
struct iterator_traits<const T*>
{
typedef T value_type;
typedef T& reference;
typedef T* pointer;
typedef ptrdiff_t difference_type;
typedef random_access_iterator_tag iterator_category;
};
因此advanced()函数可以做相应的修改
所以:advanced()函数最后可以抽象成一个实现的形式
//对外统一的接口
template<class InputIterator>
void advance(InputIterator& iter,size_t n)
{
cout<<"自制advance"<<endl;
typedef typename iterator_traits<InputIterator>::iterator_category iterator_category;
_advance(iter,n,iterator_category());//发现问题,使用STL 迭代器时,调用的是标准STL中的__advance(重载关系)
}
我的总结:
1、我们可以为每个类型定义标志符,然后在定义一个“萃取机”,将该类型作为参数就可以萃取出标志符。
2、设计适当的相应型别,是迭代器的责任。设计适当的迭代器,则是容器的责任。唯容器本身,才知道设计出怎样的迭代器来遍历自己,并执行迭代器该有的各种行为(前进,后退,取值,取用成员)。至于算法,完全可以独立于容器和迭代器之外自行发展,只要设计时以迭代器为对外接口就行。