我们知道正向迭代器的设计:begin迭代器指向第一个数据,end迭代器指向最后一个数据的下一个位置 。++移向下一个数据,解引用得到数据的值,并根据容器储存方式的不同,容器有不同类型的迭代器。
注意:rbegin迭代器指向最后一个数据的下一个位置,rend迭代器指向第一个数据,这里就体现了镜像对称,正向与反向迭代器成为对称关系。
可是,如果按照rebegin指向的位置,第一次解引用得到的应该是随机值,这是有问题的,那么stl解决方案是什么呢?它采用的方法是:解引用得到的是rebegin迭代器前一个位置的数据
为了简便,反向迭代器采用的是适配器模式,适配正向迭代器,反向迭代器的++将调用正向迭代器的--,反之亦然。
例如:
我们给出统一的反向迭代器模板,对于各容器,由模板实现各自的迭代器。给模板什么正向迭代器,它就适配出相应容器的反向迭代器
#pragma once
namespace my_ReverseIterator
{
template<class Iterator, class Ref, class Ptr>
struct ReverseIterator
{
typedef ReserveIterator<Iterator, Ref, Ptr> self;
Iterator _it;
ReverseIterator(Iterator it)
:_it(it)
{}
Ref operator*()
{
Iterator tmp = _it;
return *(--tmp); //这里没有模板类型,该返回什么类型呢?1. 萃取 2. 使用者在模板处给出
}
Ptr operator->()
{
return &(operator*());
}
self& operator++()
{
--_it;
return *this;
}
self& operator--()
{
++_it;
return *this;
}
bool operator!=(const self& s) const
{
return _it != s._it;
}
};
}
我们补充上list、vector容器的迭代器
例如:list
typedef __list_iterator<T, T&, T*> iterator; //迭代器要公有,让外面可以使用
typedef __list_iterator<T, const T&, const T*> const_iterator;
typedef ReverseIterator<iterator, T&, T*> reverse_iterator;
typedef ReverseIterator<const_iterator, const T&, const T*> const_reverse_iterator;
//用 end 适配 rbegin
reverse_iterator rbegin()
{
return reverse_iterator(end());
}
//用 begin 适配 rend
reverse_iterator rend()
{
return reverse_iterator(begin());
}
iterator begin()
{
//由指针类型隐式转换为iterator类
//return _head->_next;
//也可以用匿名对象
return iterator(_head->_next);
}
iterator end()
{
return iterator(_head);
}
例如:vector
typedef T* iterator;
typedef const T* const_iterator;
//此时反向迭代器是自定义类型
typedef ReverseIterator<iterator, T&, T*> reverse_iterator;
typedef ReverseIterator<const_iterator, const T&, const T*> const_reverse_iterator;
reverse_iterator rbegin()
{
return reverse_iterator(end());
}
reverse_iterator rend()
{
return reverse_iterator(begin());
}
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
其余容器也相同
反向迭代器也是适配器模式
最后,如果小帅的本文哪里有错误,还请大家指出,请在评论区留言(ps:抱大佬的腿),新手创作,实属不易,如果满意,还请给个免费的赞,三连也不是不可以(流口水幻想)嘿!那我们下期再见喽,拜拜!