C++【STL】之反向迭代器

文章介绍了反向迭代器的概念和其在STL中的应用,特别是在vector和list容器中的使用。反向迭代器通过结构体包装正向迭代器,实现反向遍历容器,其构造和操作符重载遵循对称原则,如rbegin()和rend()分别对应于begin()和end()。文章提供了反向迭代器的简易实现,并展示了如何在vector和list中定义和使用反向迭代器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

反向迭代器

前面在vector和list的模拟实现中都有讲到正向迭代器,今天我们就来讲解一下反向迭代器的思想和模拟实现,在某些场景下还是很实用的,下面正文直接开始。

1. 反向迭代器结构

反向迭代器reverse_iterator用于反向遍历容器,它也是由一个类来封装的

template<class Iterator>
struct __reverse_iterator
{
	Iterator _cur;	//正向迭代器类做成员变量
	__reverse_iterator(Iterator cur) //构造正向迭代器
		:_cur(cur)
	{}
    //...
};

STL库中反向迭代器的设计讲究完美的对称性,rbegin() 指向最后一个有效元素的下一个位置,rend() 指向第一个有效元素,与正向迭代器的指针位置刚好相反

拿vector对象举个例子

Self& operator++()
{
    --_cur; //正反迭代器,++,--反向操作
    return *this;
}

Self& operator--()
{
    ++_cur;
    return *this;
}

2. 反向迭代器实现

反向迭代器的实现主要还是依于对正向迭代器的复用,外加了一点小细节思想,这里我们实现的依旧是简易版本

2.1 多参数模板

前面在模拟实现list时,运用了多参数模板来解决const对象代码冗余问题,在反向迭代器的实现中也运用了相同原理,通过对形参传递不同的对象,变换为不同的迭代器

template<class Iterator, class Ref, class Ptr>
struct __reverse_iterator
{
	//...
};

其中Ref表示引用对象,Ptr表示指针对象

2.2 对称思想

STL大佬在设计反向迭代器时,为了追求与正向迭代器的对称,将首尾指针得到指向反向保持一致,如上图,即rbegin()end()位置,rend()begin()位置

在这样的设计下,rbegin()rend()的实现就可以直接对应复用了,而operator*()返回的就不是当前所指向的对象,而是成了上一个对象

reverse_iterator rbegin() 
{ 
	reverse_iterator(end()); 
}

reverse_iterator rend() 
{ 
	reverse_iterator(begin()); 
}

operator*()

Ref operator*()
{
	Iterator tmp = _cur;
	return *--tmp;	//返回上一个对象
}

2.3 完整代码

至于其他的实现都是复用的正向迭代器,比较简单,这里直接上完整代码,相信大佬,们一看就能明白

#pragma once
namespace Sakura
{
	template<class Iterator, class Ref, class Ptr>
	struct __reverse_iterator
	{
		typedef __reverse_iterator<Iterator, Ref, Ptr> self; //重命名
		Iterator _cur; //正向迭代器类做成员变量

		__reverse_iterator(Iterator cur) //构造正向迭代器
			:_cur(cur)
		{}

		Ref operator*()
		{
			Iterator tmp = _cur;
			return *--tmp;
		}

		Ptr operator->()
		{
			return &(operator*());
		}

		self& operator++()
		{
			--_cur;
			return *this;
		}

		self operator++(int)
		{
			self tmp(*this);
			--_cur;
			return tmp;
		}

		self& operator--()
		{
			++_cur;
			return *this;
		}

		self operator--(int)
		{
			self tmp(*this);
			++_cur;
			return tmp;
		}

		bool operator!=(const self& s)
		{
			return (_cur != s._cur);
		}

		bool operator==(const self& s)
		{
			return (_cur == s._cur);
		}
	};
}

3. 反向迭代器vector应用

vector 类中,定义出反向迭代器所需的函数即可

template<class T>
class vector
{
public:
	//反向迭代器
	typedef _reverse_iterator<iterator, T&, T*> reverse_iterator;
	typedef _reverse_iterator<iterator, const T&, const T*> const_reverse_iterator;

	reverse_iterator rbegin()
	{
		return reverse_iterator(end());
	}

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

	const_reverse_iterator rbegin() const
	{
		return const_reverse_iterator(end());
	}

	const_reverse_iterator rend() const
	{
		return const_reverse_iterator(begin());
	}
	//...
};

4. 反向迭代器list引用

list 类中,定义出反向迭代器所需的函数即可

template<class T>
class list
{
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()); 
	}

	const_reverse_iterator rbegin() const 
	{
		return const_reverse_iterator(end());
	}

	const_reverse_iterator rend() const 
	{ 
		return const_reverse_iterator(begin()); 
	}
	//...
};

C++【STL】之反向迭代器,到这里就介绍结束了,本篇文章对你由帮助的话,期待大佬们的三连,你们的支持是我最大的动力!

文章有写的不足或是错误的地方,欢迎评论或私信指出,我会在第一时间改正!

### C++ STL 迭代器的使用方法与示例 #### 什么是迭代器C++ STL 中的迭代器是一个重要的概念,它提供了一种统一的方式来访问和遍历容器中的元素[^1]。无论底层容器是 `std::vector`、`std::list` 或其他类型,迭代器都能屏蔽这些差异,使得开发者能够专注于算法逻辑而非数据结构细节。 --- #### 基本语法与分类 迭代器分为多种类型,常见的有输入迭代器、输出迭代器、前向迭代器、双向迭代器以及随机访问迭代器。每种类型的迭代器支持的操作不同,具体取决于其功能设计[^2]。 以下是几种常见容器及其对应的迭代器类别: - **`std::vector`**: 支持随机访问迭代器。 - **`std::list`**: 支持双向迭代器。 - **`std::map` 和 `std::set`**: 支持双向迭代器。 --- #### 示例代码:基本迭代器用法 下面展示如何使用正向迭代器遍历一个简单的 `std::vector<int>` 容器: ```cpp #include <iostream> #include <vector> using namespace std; int main() { vector<int> v = {10, 20, 30}; // 正常方式遍历 for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) { cout << *it << " "; // 输出: 10 20 30 } cout << endl; return 0; } ``` 上述代码展示了如何利用 `begin()` 和 `end()` 方法获取迭代器范围,并通过解引用操作符 (`*`) 访问当前指向的元素。 --- #### 反向迭代器 除了常规的正向迭代器外,C++ 提供了反向迭代器用于逆序遍历容器的内容。可以通过调用 `rbegin()` 和 `rend()` 获取反向迭代器实例[^3]。 以下是一段演示反向迭代器使用的代码: ```cpp #include <iostream> #include <vector> using namespace std; int main() { vector<int> v = {10, 20, 30}; // 使用反向迭代器遍历 for (vector<int>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit) { cout << *rit << " "; // 输出: 30 20 10 } cout << endl; return 0; } ``` 此代码片段说明了如何借助 `rbegin()` 和 `rend()` 实现从最后一个元素到第一个元素的遍历过程。 --- #### 需要注意的问题 尽管迭代器非常强大,但在实际开发过程中也需要注意一些潜在陷阱。例如,在某些情况下直接比较地址可能引发错误行为。如下所示的例子即为非法写法[^4]: ```cpp // 错误示范 for(auto i = v.begin(); i < v.end(); ++i){ cout << *i; } ``` 原因在于 `<` 操作符并非所有迭代器类型都定义的行为;只有当迭代器属于随机访问类型时才允许此类比较。 --- #### 总结 掌握 C++ STL迭代器不仅有助于提高程序性能,还能增强代码可读性和通用性。无论是基础的正向迭代还是高级特性如反向迭代器的应用,都需要深入理解各种容器所对应的支持能力及限制条件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

茉莉蜜茶v

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值