Iterators (迭代器)

关于迭代器, 总共有五种:

第一种迭代器是随机存取迭代器(Random access iterators)。  通过这个迭代器, 我们可以随机的存取容器中的元素。 所以, 如果我将迭代器加5, 那么我们的迭代器就向前移动5个元素(如下)等等。 注意 preincrement 比postincrement 要快, 因为preincrement 不需要返回迭代器的旧值(通常存储在一个临时变量中)。

向量(vector), 双向队列(deque), 数组(array)等容器类 都给我们提供了随机存取迭代器。

 

第二种迭代器是双向迭代器(bidirectional Iterators)。 通过这个迭代器, 我们可以对该迭代器自增(++, 对应向后移动一个元素), 自减(- -, 对应迭代器向前移动一个元素 ), 但是不能加上一个数(例如5)或者减去一个数(例如4等), 而且我们不能比较两个迭代器那个在前。

the conatiners that provide bidireactional iterators are: list, set/multiset, map/multimap。

 

第三种容器是前向迭代器(Forward Iterator)。  前向迭代器只能自增(++)运算, 从而向前移动。而且forward_list 只提供forward Iterator。

 

接下来, 对于unordered containers, 对于这类容器, 至少(at least) 这类容器 配置有forward Iterators。and they have the option to provide bidirectional iterators, depending on the implementation of the STL。

 

第四种迭代器是输入迭代器(input iterators).。 输入迭代器是用于当在向前运动迭代器的时候, 读取和处理容器中的数据的(解参考), 但是不能写。

 

第五种迭代器是输出迭代器(output iterators):  这种迭代器是用于在向前迭代过程中, 输出数据到迭代器中。

 

输入输出迭代器只能够向前迭代(forward Iterating)。

 

 

 

 

每一个容器(除了适配容器)都有一个迭代器和一个常数迭代器。

例如, 对于容器set  class , 就嵌套(nested class)了一个迭代器类(Iterator)和一个const_iterator 类。

使用常数迭代器, 只能读取容器的元素, 而不能修改容器的元素内容。 例如下面被注释掉的*citr = 3; 就不能通过编译。

C++11 提供了一个函数for_each, 是对容器中所有的元素(由前后迭代器指定), 调用函数MyFunction处理(如下例)。 函数MyFunction 只能读取容器中的元素, 而不能修改容器中的元素。

 

 

 

 

除此之外, STL也为迭代器提供了一些函数。 ;例如advance 函数用于将迭代器前移, 对于随机的迭代器, 只相当于加上一个数字。 但是这个函数是使用与所有的迭代器的(例如前向迭代器等), distance函数用于就算两个迭代器之间的距离, 而且也适用于非随机存取的迭代器。

 

另外, 还有一种特殊的迭代器。 即迭代器适配器(或者predefined Iterator).。  此类迭代器除了迭代以外, 还有更多的功能。

总共有5中Iterator adaptor。 即

(1) 插入迭代器

(2)流迭代器

(3)反向迭代器

(4) 移动迭代器

 

首先, 我们介绍一下插入迭代器(insert Iterator):

例如下面, 我们创建了两个vector对象。

然后我们在vec2中使用成员函数find查找到元素16所在的位置, 返回迭代器存储在it中。 然后我们创建一个insert_iterator的对象_itr, 指向vect2 的it(或者说内容).

 接下来, 指向copy, 将vec1 copy 到i_iter 指向的位置的前面。得到的内容如下图所示。

同理还有back_insert_iterator, 插入到尾部, front_insert_iterator 插入到容器前面。

 

接下来, 说说stream Iterator。  stream Iterator is an iterator that iterates throgh data  to and from a strream。例如下面的istream_iterator of cin,   这个迭代器将会迭代来自于标准输入的数据。 默认的建构子代表着cin 流 的end. back_inserter 是一个返回一个back_insert迭代器的函数。 在下面的例子中, 将会返回一个vec4 的back_insertde 的迭代器。 下面的那句话的作用就是将cin 中的所有的数据back_insert 到vec4 容器中。

 接下来的一句话是将vec4 中的所有内容拷贝到cout流中, 每一个element 由space(空格, “ ”)符号分隔开。

我们可以将上述的两句程序用下面一句程序代替, 这也从侧面说明标准库的强大和灵活性:

 

接下来, 对于反向迭代器(reverse Iterator): 反向迭代器的作用就是反向迭代一个容器的各个元素(in reverse order)。

STL的容器类提供一个成员函数rbegin函数, 返回的是一个指向容器最后一个元素的迭代器。  rend函数返回的是一个迭代器pointing to an element before the first element in the container .

 

 

 

最后, 我们说说STL中的算法(algorithms)

算法大部分是循环。 所以当你看到for loop, while loop 的时候, 所以在你编程序的时候, 编写了循环, 你应该想想是否可以通过调用算法中的函数一替换掉出现的循环语句。 这样会使得你的程序更加的clean, efficient, less bugs, and more readable。

例如下面的, 调用了algorithm 中的算法(函数) min_element去查找容器vec 中最小的元素。 函数返回的是指向这个最小的元素的迭代器。

我们必须清楚, 算法处理容器中的数据范围是half open(include the first item but not the last) 的, 如下图。

例如下图中, 调用了sort 函数, vec.begin() 指向第一个元素, itr指向了1 , 所以最终排序的返回是从4 到1(不含)从小到达的顺序。

调用reverse 函数的时候, itr 指向1, vec.end() 在指向最后一个元素的后面(the item after the last item).。 所以返回的是1到9.最后, itr 仍然指向原来的位置, 即现在指向了9.

对于note2:

vec2的大小至少比前面的range 大。

 

对于下面, 当我们从vec3 的后面插入的时候, 并不要求vec3的大小比前面的大。 但是这个比较安全, 缺点是效率地。

所以给出了一个efficient 和safe的方式去拷贝。 通过使用vect3的成员函数insert,  我们将itr 到 vec.end() 的元素插入到vec3.end() 的前面。

NOTE4: 函数和算法很好的结合在一起。

 

 

 

 

 

NOTE5:算法也可以作用于C++ 的普通数组(指针可以被想象成为迭代器)。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值