【C++STL】迭代器

迭代器:

1.迭代器的设计:

不管是泛型思维或是STL的实际应用,迭代器都扮演着重要的角色。
STL的中心思想:
将容器和算法分开。彼此独立设计,然后再将它们粘合在一起。
从技术角度并不困难,C++的class template和function template都可以分别达成目标。
如何设计出两者之间的良好的粘合剂,才是最大的问题。
举个例子:
利用模板函数,使得迭代器和容器之间关联。

template<typename _BI,typename _Ty>
_BI my_find(_BI _first,_BI _last,const _Ty &val)
{
    cout<< typeid(_BI).name()<<endl;
    for(;_first !_last;++_first)
    {
    if(*_first == val)
    {
      break;
    }
    }
    return _first;
}

不论什么容器都可以使用该算法。

int main()
{
   vector<int> vec = {12,23,34,45,56};
   list<int> ilist = {12,23,34,45,56};
   deque<int> deq = {12,23,34,45,56};
   vector<int> ::iterator it = my_find(vec.begin(),vec.end(),34);
   cout<<*it<<endl;
    list<int> ::iterator il = my_find(ilist.begin(),ilist.end(),45);
      cout<<*il<<endl;
    deque<int> ::iterator ide = my_find(deq.begin(),deq.end(),56);
      cout<<*ide<<endl;
}

请添加图片描述

2. 迭代器是一种 smart pointer

  1. 迭代器是一种类似指针的对象,而指针的行为。
  2. 最常用也最重要的是 【内容提取】和【成员访问】
    意思就是主要工作由下面两个函数来实现。
    _Ty &operator *() const { return pointer; }
    _Ty
    operator ->()const {return pointer;}

3.迭代器的5种相应类型

value_type

所谓value_type ,是指迭代器所指的对象的型别。
任何一个打算和STL算法有完美搭配的class,都应该定义自己的value_type内嵌型别。

difference_type

difference_type:表示两个迭代器之间的距离.
因此它也可以用来表示一个容器的最大容量。因为对于连续空间的容器而言,头尾之间的距离就是其最大容量。
如果一个泛型算法提供计数功能,例如 STL的count(),其传回值就必须使用迭代器的difference_type;

template<typename I,typename T>
typename iterator_traits<I>::difference_type
count(I first, I last, T val)
{
	iterator_traits<I>::difference_type n = 0;
	for (; first != last; first++)
	{
		if (*first == val)
		{
			++n;
		}
	}
	return n;
}

reference_type

迭代器所指之物的内容是否允许被改变?
因此迭代器分为两种:constant iterator 和 mutable iterator
当我们对mutable iterator进行提领操作,获得的不应该是右值(rvalue),而应该是左值(lvalue),因为右值不允许赋值操作,左值才允许。

pointer_type

pointers 和 references 在 C++中有非常密切的关联。如果“传回一个左值,
左值,令它代表p所指之物的,是可能的,那么“传回一个地址”也一定可以。
也就是说,我们能够传回一个pointer,指向迭代器所指之物。
示例:

Item& operator*() const { return *ptr; }
Item* operator->() const { return ptr; }
               
template<typename _C, typename _Ty, typename _D = ptrdiff_t,
		typename _Pointer = _Ty*, typename _Reference = _Ty&>
		struct iterator                      
	{
		typedef _C			iterator_category;   //迭代器类型
		typedef _Ty			value_type;          //迭代器所指之物的值类型
		typedef _D          difference_type;      //差值类型
		typedef _Pointer    pointer;              //迭代器所指之物的引用类型
		typedef _Reference  reference;           //迭代器所指之物的指针类型
	};

iterator_category

  • Input_iterator
  1. 特点:只读,不写,只扫描一遍,只能递增。
  2. 输入迭代器可以读取序列中的元素。
    输入迭代器只用于顺序访问对于一个输入迭代器,*iter++保证是有效的,但递增它可能导致所有其他指向流的迭代器失效,所以输入迭代器只能用于单遍扫描算法。
    输入迭代器必须支持
  3. 用于比较两个迭代器相等和不相等运算符(==, !=)
  4. 用于推进迭代器的前置和后置递增运算符(++)
  5. 用于读取元素的解引用运算符(*);解引用只会出现在赋值运算符的右侧(因为输入迭代器只读不写)
  6. 箭头运算符(->),等价于(*it).member,即,解引用迭代器,并提取对象的成员
  • Output_iterator :唯写(write only)
    特点:只写,不读;单遍扫描,只能递增;
    输出迭代器必须支持
  1. 用于推进迭代器的前置和后置递增运算(++);
  2. 解引用运算符(*),只出现在赋值运算符的左侧(因为输出迭代器只写不读)(向一个已经 解引用的输出迭代器赋值,就是将值写入它所指向的元素);
    我们只能向一个输出迭代器赋值一次,类似于输入迭代器,输出迭代器也只能用于单遍扫描算法

  • Forward_iterator:允许“写入型”算法,正向迭代器。
    特点:可读写,多遍扫描,只能递增
    前向迭代器支持
  1. 可以读写元素,这类迭代器只能在序列中沿一个方向移动。
  2. 前向迭代器支持所有输入和输出迭代器的操作,而且可以多次读写同一元素。
  3. 可以保存前向迭代器的状态,使用前向迭代器的算法可以对序列进行多遍扫描。
  • Bidirectional_iterator:双向迭代器,某些算法需要逆向访问某个迭代器区间。
    特点:可读写,多遍扫描,可能递增递减
    双向迭代器支持:
  1. 可以正向/反向读写序列中的元素。
  2. 除了支持所有前向迭代器的操>作之外,双向迭代器还支持前置和后置递减运算符.
  • Random_access_iterator:随机性迭代器,涵盖所有指针操作
    特点:可读写,多遍扫描,支持全部迭代器运算
    随机访问迭代器提供在常量时间内访问任意元素的能力。此类迭代器支持双向迭代器的所有功能此外,还支持:
  1. 用于比较两个迭代器相对位置的关系运算符(<,<=,>,>=)
  2. 迭代器和一个整数值的加减运算(+,+=,-,-=),计算结果迭代器在序列中前进(后退)给定整数个元素后的位置
  3. 用于两个迭代器上的减法运算符号(-),得到两个迭代器的距离
  4. 下标运算符(iter[n])等价于*(iter[n])
//输入迭代器标志域
struct input_iterator_tag {};
//输出迭代器标志域
struct output_iterator_tag {};
//前向迭代器标志域 继承 输入,输出迭代器的所有功能
struct forward_iterator_tag : public input_iterator_tag {};
//双向迭代器标志域 继承 前向迭代器
struct bidirectional_iterator_tag : public forward_iterator_tag {};
//随机迭代器,继承 双向迭代器
struct random_access_iterator_tag : public bidirectional_iterator_tag {};

萃取器:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值