当前位置: 首页 > wzjs >正文

网站运营推广方案营销型网站建设的公司

网站运营推广方案,营销型网站建设的公司,网站的css文件夹,网站开发进度计划是什么反向迭代器的实现思路 源码及框架分析 迭代器是用来遍历容器的,是一种封装,它不需要去关注容器的底层实现(底层是数组,链表,还是树等等这些结构),我们都是用统一的方式去对容器进行访问&#…

反向迭代器的实现思路

源码及框架分析

迭代器是用来遍历容器的,是一种封装,它不需要去关注容器的底层实现(底层是数组,链表,还是树等等这些结构),我们都是用统一的方式去对容器进行访问,访问行为是类似指针的。我们之前学习了普通迭代器和const迭代器:

  • 普通迭代器:能读能写;
  • const迭代器:只能读,只能遍历数据,得到数据,不能修改数据,是不能写的。

我们之前学的普通迭代器是正向迭代器,如果我想逆方向遍历呢?那么就需要反向迭代器。

SGI-STL30源代码,反向迭代器实现的核心源码在stl_iterator.h中,反向迭代器是一个适配器,各个容器中再适配出自己的反向迭代器,我们下面来看一看vector容器和list容器中的反向迭代器的核心部分:

在源码中,我们可以看到 reverse_iterator 实现了两个版本。通过 __STL_CLASS_PARTIAL_SPECIALIZATION 条件编译来控制使用哪个版本。简单来说,支持偏特化的迭代器萃取以后,反向迭代器使用的是以下版本:

template <class Iterator> 
class reverse_iterator;

而之前使用的是以下版本:

template <class BidirectionalIterator, class T, class Reference, class Distance> 
class reverse_bidirectional_iterator;template <class RandomAccessIterator, class T, class Reference, class Distance> 
class reverse_iterator;

可以看到,它们的主要差别在于模板参数是否传递迭代器指向的数据类型。支持偏特化的迭代器萃取以后,就不需要手动传递数据类型,因为 reverse_iterator 内部可以通过迭代器萃取获取数据类型。迭代器萃取的本质是一种特化,我们主要使用通过模板参数传递数据类型的方式来实现。

反向迭代器本质上是一个适配器,使用模板实现。传递哪个容器的迭代器,就可以封装适配出对应的反向迭代器。因为反向迭代器的功能与正向迭代器的功能高度相似,只是遍历方向相反,例如 operator++ 底层调用迭代器的 operator-- 等,所以通过封装就可以实现。

比较奇怪的是 operator* 的实现。它内部访问的是迭代器当前位置的前一个位置。这需要结合容器中 rbeginrend 的实现才能理解。rbegin 返回的是封装 end 位置的反向迭代器,rend 返回的是封装 begin 位置迭代器的反向迭代器。这里的设计是为了实现一种对称性,因此解引用访问的是当前位置的前一个位置。



反向迭代器的实现

反向迭代器通常是通过正向迭代器进行构造的。反向迭代器本质上是一个适配器,它对正向迭代器进行封装,从而实现反向遍历的功能。

反向迭代器的析构也不需要我们自己实现,因为迭代器不负责释放资源,释放资源是容器的事情!所以析构不需要写,就一般不需要写拷贝构造,因为不需要进行深拷贝!默认生成的浅拷贝就够用了! 

重点实现的是:

operator*operator->operator++operator--

operator* 就是要返回当前迭代器指向的数据,当前指向的位置是一个正向迭代器,上面的对象是包装了一个反向迭代器的。operator* 解引用,不管是正向还是反向,都要返回数据的引用! 

返回值类型设置 

对于反向迭代器来说,operator* 的行为确实需要特别注意。反向迭代器的目的是让遍历方向与正向迭代器相反,因此它的 operator* 需要返回当前迭代器所指位置的前一个元素。这是因为反向迭代器的逻辑起点是容器的末尾(end()),而不是开头(begin())。

  • 正向迭代器begin() 指向第一个元素,end() 指向最后一个元素的下一个位置。

  • 反向迭代器rbegin() 指向最后一个元素,rend() 指向第一个元素的前一个位置。

因此,反向迭代器的 operator* 实现为:

T& operator*() const { return *(current - 1); }

这里 current 是存储的正向迭代器,current - 1 表示前一个位置。

反向迭代器的模板参数

反向迭代器的模板参数设计取决于迭代器的类型和容器的特性。主要有以下两种情况:

a. 通用模板参数

对于通用的反向迭代器,模板参数通常包括:

  • Iterator:正向迭代器类型。

  • T:迭代器所指元素的类型。

  • Reference:引用类型(T&const T&)。

  • Distance:迭代器距离类型(如 std::ptrdiff_t)。

template <class Iterator, class T, class Reference, class Distance>
class reverse_iterator {
public:Reference operator*() const { return *(current - 1); }// 其他成员函数...
private:Iterator current;
};
b. 偏特化和类型萃取

对于某些容器(如 std::vector),其迭代器可能是原生指针,没有内嵌类型(如 referencevalue_type)。这种情况下,需要通过偏特化或类型萃取来获取正确的类型信息。

  • std::list 的迭代器:是一个自定义类型,可以通过 typename Iterator::reference 获取引用类型。

  • std::vector 的迭代器:是一个原生指针,没有内嵌类型,需要通过偏特化或类型萃取来获取正确的类型。

template <class Iterator>
class reverse_iterator {
public:// 使用类型萃取获取引用类型using reference = typename std::iterator_traits<Iterator>::reference;reference operator*() const { return *(current - 1); }// 其他成员函数...
private:Iterator current;
};

为什么需要偏特化或类型萃取

  • std::list 的迭代器:是一个类模板实例,具有内嵌类型(如 referencevalue_type)。因此,可以直接通过 typename Iterator::reference 获取引用类型。

  • std::vector 的迭代器:是一个原生指针(如 T*),没有内嵌类型。因此,需要通过偏特化或类型萃取来获取正确的类型。

template <class T>
class reverse_iterator<T*> {
public:using reference = T&;reference operator*() const { return *(current - 1); }// 其他成员函数...
private:T* current;
};
  • operator* 的行为:反向迭代器的 operator* 返回当前迭代器所指位置的前一个元素。

  • 模板参数设计:通用模板参数可以处理大多数情况,但对于原生指针类型的迭代器,需要通过偏特化或类型萃取来获取正确的类型信息。

  • 类型萃取:通过 std::iterator_traits 可以统一处理不同类型迭代器的特性,包括原生指针和自定义迭代器。

其实就是总结为:

如果是普通迭代器,那就适配出普通反向迭代器:T& operator*,如果是const迭代器,就适配出const反向迭代器:const T& operator*,只是template<class Iterator>的话,是不能够的,Iterator内部有没有该数据类型?list是有的,以为list的iterator是一个自定义类型,直接使用typename Iterator::reference,也就是取他的内嵌类型(取内嵌类型需要加typename),但是vector就是一个原生指针,没有内嵌类型的概念,这时候就需要偏特化的类型萃取才可以搞定!

其实我们这里就不要那么复杂了,使用三个模板参数就可以了!

template<class Iterator, class Ref, class Ptr>

下面,为我们就可以实现一个:

Iterator.h

#pragma once// 反向迭代器模板
template<class Iterator, class Ref, class Ptr>
struct ReverseIterator
{typedef ReverseIterator<Iterator, Ref, Ptr> Self; // 自引用类型别名,方便后续使用// 构造函数:接受一个正向迭代器ReverseIterator(Iterator it): _it(it) // 初始化内部存储的正向迭代器{}// 解引用操作符:返回当前迭代器前一个位置的引用Ref operator*(){// 适配的不一定是随机迭代器,可能是双向迭代器或输入迭代器// 不是双向迭代器又不能减,只可以进行减减// 而且不能直接对_it"--"解引用,因为这会改变_it的值// 创建一个临时迭代器,向前移动一位Iterator tmp = _it;--tmp; // 确保迭代器支持--操作// 返回前一个位置的引用return *tmp;}// 成员访问操作符:返回解引用的地址Ptr operator->(){return &(operator*()); // 复用 operator* 的实现}// 前置递增操作符:递减内部迭代器Self& operator++(){--_it; // 内部迭代器向前移动return *this; // 返回当前反向迭代器}// 前置递减操作符:递增内部迭代器Self& operator--(){++_it; // 内部迭代器向后移动return *this; // 返回当前反向迭代器}// 不等于操作符:比较两个反向迭代器是否不相等bool operator!=(const Self& s){return _it != s._it; // 比较内部迭代器}// 等于操作符:比较两个反向迭代器是否相等bool operator==(const Self& s){return _it == s._it; // 比较内部迭代器}Iterator _it; // 内部存储的正向迭代器
};

我们就可以在List.h中进行反向迭代器的使用了:(结合上面图片进行代码的编写)

		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;//reverse_iterator rbegin()//{//	return reverse_iterator(--end());//}//reverse_iterator rend()//{//	return reverse_iterator(end());//}// 对称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());}

 我们就可以在Vector.h中进行反向迭代器的使用了:

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());}const_reverse_iterator rbegin() const{return const_reverse_iterator(end());}const_reverse_iterator rend() const{return const_reverse_iterator(begin());}iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}

附录

迭代器类别支持的操作示例
输入迭代器 (Input Iterator)单向遍历,支持 ++*->std::istream_iterator
输出迭代器 (Output Iterator)单向写入,支持 ++*std::ostream_iterator
前向迭代器 (Forward Iterator)双向遍历,支持 ++*->std::forward_list::iterator
双向迭代器 (Bidirectional Iterator)双向遍历,支持 ++--*->std::list::iteratorstd::map::iterator
随机访问迭代器 (Random Access Iterator)随机访问,支持 ++--+-[]*->std::vector::iteratorstd::deque::iterator

本片的全部正文:

反向迭代器https://gitee.com/small-entrepreneur/c-additional-meal

http://www.dtcms.com/wzjs/106393.html

相关文章:

  • 仙桃网站建设海外推广营销 平台
  • 邢台做网站优化谷歌浏览器下载官方正版
  • dz做电影网站seo霸屏软件
  • python做网站还是数据怎么优化
  • 武汉招聘一般用什么网站世界杯数据分析
  • 在易语言里面做网站百度自然排名优化
  • 在县城怎么做网站公司写一篇软文1000字
  • 四川省建设注册资格中心网站百度注册
  • 需要个网站排名优化公司哪家好
  • 濮阳网格化appwindows优化大师怎么使用
  • 自己做网站要办手续吗微营销推广方案
  • 佛山网站开发百度seo价格查询
  • 哪里做外贸网站有没有帮忙推广的平台
  • 做软件赚钱的网站有哪些百度在线客服
  • 宁波网站建设网站推广一般收多少钱
  • 做网站挣钱来个好心人指点一下呗网站排名查询平台
  • 多种语言网站怎么做广州白云区新闻头条最新消息今天
  • 一些做设计素材的网站aso关键词排名优化是什么
  • 大连网站建设那家好seo推广代运营
  • 网站一级页面二级页面怎么做湖南竞价优化哪家好
  • 怎样建设一个好的网站seo技术培训广东
  • wordpress申请网站吗兰州网络推广的平台
  • 一份电子商务网站建设规划书企业营销策划方案范文
  • 建设隔离变压器移动网站营销广告文案
  • 佛山新网站建设如何免费二级域名分发网站源码
  • 怎么做网站分站黄金网站软件app大全下载
  • 尼尔的h版是那个网站做的杭州上城区抖音seo如何
  • 一级造价工程师含金量北京官网seo
  • 自己做网站难不难谷歌搜索为什么用不了
  • 品牌创意型网站开发网站建设多少钱