反向迭代器是C++ STL(标准模板库)中的一种迭代器类型,它允许我们逆向遍历容器(如std::vector, std::list, std::deque
等)中的元素。反向迭代器指向容器的“尾部”元素,并通过递减操作向前移动(即向容器的开始方向移动)。
通过前面list的模拟实现知道,反向迭代器的++就是正向迭代器的--,反向迭代器的--就是正向迭代器的++,因此反向迭代器的实现可以借助正向迭代器,即:反向迭代器内部可以包含一个正向迭代器,对正向迭代器的接口进行包装即可。
一、反向迭代器的类模板参数
template<class Iterator>
//Iterator为正向迭代器,反向迭代器复用正向迭代器的相反操作实现
反向迭代器的模板参数class Ref与class Ptr可以省略,因为Iterator内部同样有模板参数class Ref与class Ptr。
typedef typename Iterator::Ref Ref;//与正向迭代器相同,operator*()的返回值类型
typedef typename Iterator::Ptr Ptr;//operator->()的返回值类型
注意:此处typename的作用是明确告诉编译器,Ref是Iterator类中的类型,而不是静态成员变量。
二、反向迭代器的封装
封装实现反向迭代器, 要先定义一个Iterator cur成员变量以复用Iterator的运算符操作。
构造函数:
template<class Iterator, class Ref, class Ptr>
struct ReverseIterator
{typedef ReverseIterator<Iterator, Ref, Ptr> Self;Iterator cur;ReverseIterator(Iterator it):cur(it){}
};
operator*()与operator->():
反向迭代器是正向迭代器的逆置,其rbegin()为第一个元素为Iterator的最后一个元素的下一个,因此反向迭代器的operator*()需要访问元素先进行--操作。
Ref operator*() {Iterator tmp = cur;//访问元素由tmp进行--操作--tmp;return *tmp;
}//operator->()复用operator*(),&operator*()为节点数据的地址
Ptr operator->() {return (&operator*());
}
前置++、--和后置++、--:
反向迭代器的++就是正向迭代器的--,反向迭代器的--就是正向迭代器的++。
Self& operator++() {--cur;return *this;
}Self operator++(int) {Iterator tmp(cur);--cur;return tmp;
}Self& operator--() {++cur;return *this;
}Self operator--(int) {Iterator tmp(cur);++cur;return tmp;
}
反向迭代器的比较与正向迭代器一致:
bool operator!=(const Self& s) {return cur != s.cur;
}bool operator==(const Self& s) {return cur == s.cur;
}
三、rbegin()与rend()
reverse_iterator rbegin() {return reverse_iterator(end());
}reverse_iterator rend() {return reverse_iterator(begin());
}
完整实现如下 :
template<class Iterator, class Ref, class Ptr>
struct ReverseIterator {typedef ReverseIterator<Iterator, Ref, Ptr> Self;Iterator cur;ReverseIterator(Iterator it):cur(it){}Self& operator++() {--cur;return *this;}Self operator++(int) {Iterator tmp(cur);--cur;return tmp;}Self& operator--() {++cur;return *this;}Self operator--(int) {Iterator tmp(cur);++cur;return tmp;}Ref operator*() {Iterator tmp = cur;--tmp;return *tmp;}Ptr operator->() {return (&operator*());}bool operator!=(const Self& s) {return cur != s.cur;}bool operator==(const Self& s) {return cur == s.cur;}
};