Bootstrap

【反向迭代器】—— 我与C++的不解之缘(十七)

前言

​ 在STL中的迭代器部分,之前只关注与正向迭代器,忽视了反向迭代器;现在来看一下反向迭代器到底是个什么东西,以及反向迭代器怎么实现,怎么为之前自己模拟实现的容器增加反向迭代器?

反向迭代器的使用

​ 首先,先来看一下反向迭代器是个什么东西,怎么使用?
在这里插入图片描述

这里以vectorlist 为例,看一下正向迭代器和反向迭代器的区别。

vector 的反向迭代器

#include<iostream>
#include<vector>
#include<list>

using namespace std;
void test_vector()
{
	vector<int> v;
	int arr[] = { 1,2,3,4,5,6,7,8,9 };
	for (auto e : arr)
	{
		v.push_back(e);
	}
	//正向迭代器
	vector<int>::iterator it = v.begin();
	cout << "正向迭代器遍历: ";
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	//反向迭代器
	vector<int>::reverse_iterator rit = v.rbegin();
	cout << "反向迭代器遍历: ";
	while (rit != v.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;
}

int main()
{
	test_vector();

	return 0;
}

输出结果:

正向迭代器遍历: 1 2 3 4 5 6 7 8 9
反向迭代器遍历: 9 8 7 6 5 4 3 2 1

list 的反向迭代器

void test_list()
{
	list<int> l;
	int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
	for (auto e : arr)
	{
		l.push_back(e);
	}
	list<int>::iterator it = l.begin();
	cout << "正向迭代器遍历: ";
	while (it != l.end())
	{
		cout << *it << ' ';
		++it;
	}
	cout << endl;

	list<int>::reverse_iterator rit = l.rbegin();
	cout << "正向迭代器遍历: ";
	while (rit != l.rend())
	{
		cout << *rit << ' ';
		++rit;
	}
	cout << endl;
}

int main()
{
	//test_vector();
	test_list();
	return 0;
}
正向迭代器遍历: 1 2 3 4 5 6 7 8 9 0
正向迭代器遍历: 0 9 8 7 6 5 4 3 2 1

​ 通过结果,我们可以看到,无论是vector 还是list 正向迭代器是正向遍历,而反向迭代器则是反向遍历。

再回过头看rbeginrend 函数:

  • rbegin 函数,返回容器一个指向容器最后一个元素的反向迭代器。。
  • rend 函数,返回容器表示反向迭代结束的反向迭代器。

反向迭代器的模拟实现

​ 看完反向迭代器的使用,那反向迭代器到底是如何实现的呢?

如果第一次看到这个问题,感觉会和第一次看到const_iterator 那样,想着去单独实现一个反向迭代器,但是那样太麻烦了。

根据正向迭代器和反向迭代器的使用比较,我们发现几个特点:

  • 反向迭代器的++ 相当于正向迭代器的--
  • 反向迭代器的-- 相当与正向迭代器的++

​ 那么这样,我们是不是就可以考虑将反向迭代器写成一个模板呢,只要你给我传模板参数(iterator 正向迭代器),我就能给你生成其对应的反向迭代器。

反向迭代器实现模板:

namespace HL
{
	template<class Iterator, class Ref, class Ptr>
	class my_reverse_iterator
	{
		typedef my_reverse_iterator<Iterator, Ref, Ptr> self;
	public:
		my_reverse_iterator() {}
		my_reverse_iterator(const Iterator& it)
		{
			_it = it;
		}
		self operator--()
		{
			Iterator ret = _it;
			--_it;
			return ret;
		}
		self operator--(int)
		{
			--_it;
			return _it;
		}
		self operator++()
		{
			Iterator ret = _it;
			++_it;
			return ret;
		}
		self operator++(int)
		{
			++_it;
			return _it;
		}
		bool operator==(const self& it) const
		{
			return _it == it._it;
		}
		bool operator!=(const self& it) const
		{
			return _it != it._it;
		}
		Ref operator*()
		{	
             Iterator tmp = _it;
			return *(--tmp);
		}
		Ptr operator->()
		{
			return _it->;
		}
	private:
		Iterator _it;
	};
}

​ 到这里,反向迭代器就简单的实现出来了(自己写的与库里面的不一样),现在来对应一下vectorlist

vector

​ 这里用一下之前的代码,来对应使用一个反向迭代器。

源代码链接:study/study_11_17_反向迭代器 · 努力学习的小廉/C++学习 - 码云 - 开源中国

由于代码过长,这里就只显示增加的部分了。

	public:
		typedef reverse_iterator<iterator, T&, T*> reverse_iterator;
		typedef reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;
		reverse_iterator rbegin()
		{
			return reverse_iterator(end());
		}
		reverse_iterator rend()
		{
			return reverse_iterator(begin());
		}
		

list

	public:
		typedef reverse_iterator<iterator, T&, T*> iterator;
		typedef reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;

		reverse_iterator rebgin()
		{
			return reverse_iterator(end());
		}
		reverse_iterator rend()
		{
			return reverse_iterator(begin());
		}

​ 我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2oul0hvapjsws

;