目录
1.返向迭代器结构
2.反向迭代器原理
能用上反向迭代器, 说明容器支持双向读取,双向迭代器
那么是不是所以的满足这个条件的迭代器本身也有满足反向迭代器的潜质
所以反向迭代器是一个面向迭代器的类的封装,范性编程
反向迭代器的模板参数就是这个迭代器的类型
3.反向迭代器实现重载
1. 构造函数: 使用迭代器来构造
Iterator(node* x)
:_it(x)
{}
Reverse_Iterator(iteartor x)
:rit(x)
{}
reverse_iterator rend()
{
return iterator(_head->_next);
}
这里iterator内部就是一个指针,可以用指针构造一个iterator对象
iterator对象又可以作为reverse_iterator的参数去构建
在第三个里函数的返回值是reverse_iterator类型,而返回的对象是一个iterator对象
这中间发生了隐式类型转化,当自定义类型的构造函数只有一个参数就可以进行隐式类型转换
2. operator++ 其实是类成员--iterator
self operator++()
{
--rit;
return *this;
}
3. operator-- 其实是类成员++iterator
self operator--()
{
++rit;
return *this;
}
4. operator* 其实是类成员先找到前一个再--返回解引用后的内容
Ref operator*()
{
iteartor tmp = rit;
return *(--tmp);
}
5.operator-> 其实是类成员先找到前一个再--返回取地址后的内容
Ptr operator->()
{
return &(operator*());
}
6. operator!=
bool operator!=(const self& x) const
{
return rit != x.rit;
}
4. 反向迭代器模拟实现(没有萃取)
#pragma once
namespace kele
{
template<class iteartor, class Ref, class Ptr>
struct Reverse_Iterator
{
typedef Reverse_Iterator<iteartor, Ref, Ptr> self;
iteartor rit;
Reverse_Iterator(iteartor x)
:rit(x)
{}
Ref operator*()
{
iteartor tmp = rit;
return *(--tmp);
}
Ptr operator->()
{
return &(operator*());
}
self operator++()
{
--rit;
return *this;
}
self operator++(int)
{
self tmp = *this;
--rit;
return tmp;
}
self operator--()
{
++rit;
return *this;
}
self operator--(int)
{
self tmp = *this;
++rit;
return tmp;
}
bool operator!=(const self& x) const
{
return rit != x.rit;
}
bool operator==(const self& x) const
{
return rit == x.rit;
}
};
}
5. 迭代器隐式类型转化
自己实现的list可能会出现下面这种情况
int main()
{
int arr[] = { 1,7,4,6,9,8,0 };
kele::list<int> t(arr, arr + 7);
kele::list<int>::const_iterator rit = t.begin();
while (rit != t.end())
{
cout << *rit << " ";
++rit;
}
cout << endl;
return 0;
}
error C2440: “初始化”: 无法从“kele::__list_iterator<T,T &,T *>”转换为“kele::__list_iterator<T,const T &,const T *>”
对于自定义类型一般编译器不会进行隐式类型转换,但是如果在自定义类型的中存在一个只有一个参数的构造函数,就会发生隐式类型转换
6. 反向迭代器萃取
萃取,个人理解,从模板参数反向推导模板所对应的类内的类型
从下面的例子:
template <class T>
struct MyIter {
typedef T value_type;
T* ptr;
MyIter(T* p) {
ptr = p;
}
T& operator*() {
return *ptr;
}
};
template <class I>
typename I::value_type
func(I ite) { // typename I::value_type 为返回值类型
return *ite;
}
int main()
{
MyIter<int> ite(new int(1231));
cout << func(ite);
return 0;
}
此处 typename 的作用是告诉编译器这是一个类型,因为 I 是一个模板参数,在它被具现化之前编译器对它一无所知,也就是说编译器不知道 I::value_type 是个类型或是成员函数等等。
例子来自:http://t.csdnimg.cn/oCoKA
反向迭代器传参其实只需要一个,另外两个类型都可以萃取推导出来
对应反向迭代器的类模板参数只需要iterator
直接萃取
直接萃取对于自定义类型的iterator且类内部存在 value_type 等类型可以实现
但是对于 Iterator 是原生指针 这种就不行,内置类型不能萃取,因为不存在 value_type 类型
还有一种办法 构建迭代器萃取器
这里利用 类模版的偏特化 针对模板参数更进一步的条件限制所设计出来的一个特化版本
C++ 模板http://t.csdnimg.cn/4nmel反向迭代器的隐式类型转化
这里有没有可能发生 const_reverse_iterator 转换成 reverse_iterator 权限放大?
有可能,但是不是完全可能
反向迭代器的构造在这一句 :rit(x.rit) 实现
问题就转换了,变成了 const_iterator 构造成 iterator
如果底层迭代器实现没有问题,反向迭代器就不会有问题
7. 反向迭代器模拟实现(萃取版)
#pragma once
namespace kele
{
template <class Iterator>
struct iterator_traits {
typedef typename Iterator::value_type value_type;
typedef typename Iterator::pointer pointer;
typedef typename Iterator::reference reference;
};
template <class T>
struct iterator_traits<T*> {
typedef T value_type;
typedef T* pointer;
typedef T& reference;
};
template <class T>
struct iterator_traits<const T*> {
typedef T value_type;
typedef const T* pointer;
typedef const T& reference;
};
template<class Iteartor>
struct Reverse_Iterator
{
typedef typename iterator_traits<Iteartor>::value_type value_type;
typedef typename iterator_traits<Iteartor>::reference reference;
typedef typename iterator_traits<Iteartor>::pointer pointer;
typedef Reverse_Iterator<Iteartor> self;
Iteartor rit;
Reverse_Iterator(Iteartor x)
:rit(x)
{}
template<class iter>
Reverse_Iterator(const Reverse_Iterator<iter>& x)
:rit(x.rit)
{}
reference operator*()
{
Iteartor tmp = rit;
return *(--tmp);
}
pointer operator->()
{
return &(operator*());
}
self operator++()
{
--rit;
return *this;
}
self operator++(int)
{
self tmp = *this;
--rit;
return tmp;
}
self operator--()
{
++rit;
return *this;
}
self operator--(int)
{
self tmp = *this;
++rit;
return tmp;
}
bool operator!=(const self& x) const
{
return rit != x.rit;
}
bool operator==(const self& x) const
{
return rit == x.rit;
}
};
}
完