Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1853256
  • 博文数量: 184
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2388
  • 用 户 组: 普通用户
  • 注册时间: 2016-12-21 22:26
个人简介

90后空巢老码农

文章分类

全部博文(184)

文章存档

2021年(26)

2020年(56)

2019年(54)

2018年(47)

2017年(1)

我的朋友

分类: C/C++

2018-08-18 00:04:25

咳咳,今天来说一下迭代器这个东西à iterator。

说实话,当初学stl的时候,就觉得这东西很神奇,很强大,但是又没有深入了解过这个东西,只是觉得这东西像个指针一样,但是又比指针好用。这次看完这这一章之后,对这个东西的理解又深刻了一点。

首先,iterator这个东西是为了将stl当中的容器与算法连接起来而出现的产物,具体开发工作由容器设计者来完成,大概如下:



这样做有两个好处:

1. 将容器的开发工作和算法的开发工作完全分离开来

2. 避免对外界暴露更多容器的实现细节

但是,这样做的话会有一个问题,当算法模板当中需要用到迭代器所指的对象的类型时,心里唱起了凉凉,哎,咋就这么惨呢?聪明的stl设计者们就设计了如下的思路来“萃取”出迭代器所指对象的类型和其他的一些特性,如下图和代码:




点击(此处)折叠或打开

  1. template <class Iterator>
  2. struct iterator_traits{
  3.     typedef typename Iterator::value_type value_type;
  4.     typedef typename Iterator::iterator_category iterator_category;
  5.     typedef typename Iterator::difference_type difference_type;
  6.     typedef typename Iterator::pointer pointer;
  7.     typedef typename Iterator::reference reference;
  8.     …
  9. };

这里要说明一下iterator_category, 其设计原由就是:stl设计者为了程序执行效率考虑,为每一种容器都设计了不同的迭代器,例如:只允许++操作的forward_iterator,允许++--操作的bidirectional_iterator,允许++--、和+n-n操作的random_access_iterator

有了迭代器所指的对象的类型,以及其自身得性质,就轮到stl中算法大显身手了,由于函数模板是可以自行推导出参数类型,进而进行函数调用的,所以,我们只需要在stl函数模板中实现函数重载就ok了,这里就要用到上面说的iterator_category了,具体代码如下:



点击(此处)折叠或打开

  1. //先声明一堆空的结构体来确定各个iterator的category:
  2. struct input_iterator_tag {};
  3. struct output_iterator_tag {};
  4. struct forward_iterator_tag : public input_iterator_tag {};
  5. struct bidirectional_iterator_tag : public forward_iterator_tag {};
  6. struct random_access_iterator_tag : public bidirectional_iterator_tag {};
  7. //之后就是对各个函数的模板进行重载了:
  8. template <class InputIterator, class Distance>
  9. inline void __distance(InputIterator first, InputIterator last, Distance& n,
  10.                        input_iterator_tag) {
  11.   while (first != last) { ++first; ++n; }
  12. }

  13. template <class RandomAccessIterator, class Distance>
  14. inline void __distance(RandomAccessIterator first, RandomAccessIterator last,
  15.                        Distance& n, random_access_iterator_tag) {
  16.   n += last - first;
  17. }
  18. //甩给外界的接口就是:
  19. template <class InputIterator, class Distance>
  20. inline void distance(InputIterator first, InputIterator last, Distance& n) {
  21.   __distance(first, last, n, iterator_category(first));
  22. }

当外界调用distance函数的时候,首先会根据输入的iterator类型,选区不同的category,进而调用不同的内嵌函数模板,这样就完成了之前所说的~~
阅读(1839) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~