迭代器模式

提供一种方法,使之能够依序访问容器的各个元素,而又无需暴露容器的内部表述方式

STL设计的中心思想在于将数据容器算法分离开,容器和算法分开设计,迭代器则是两者之间的胶着剂,一般迭代器的设计与容器细节相关,所以一般交给容器的设计者

迭代器相应型别

如何"获取迭代器的所指对象的型别"? 可以借助参数推导,但函数的返回值是无法推导的,如果声明内嵌型别typedef T value_type,那么对于原始指针就无法定义其内嵌型别,这时候模板偏特化可以做到

偏特化与traits

泛型思维对偏特化的定义是"针对template参数更进一步的条件限制所设计的一个特化版本"

我们可以使用

template <class I>
struct iterator_traits {
    typedef typename I::value_type value_type;
};
// 针对原始指针的特化版本
template <class T>
struct iterator_traits<T*> {
    typedef T value_type;
};
// 针对原始常量指针的特化版本
template <class T>
struct iterator_traits<const T*> {
    typedef T value_type;
};

常用迭代器型别

根据经验常用的迭代器相应型别有5种: value_type,difference_type,pointer,reference,iterator_catagoly

  • value_type 如上,萃取出迭代器所指对象的类型
  • difference_type 表示两个迭代器之间的距离,如STL中的count
  • reference_type 根据是否允许改变“所指对象之内容”分为两种:constant iterator(如const int* p)和mutable iterator(如int* p)
  • pointer 指向迭代器所指之物
  • iterator_category

根据移动操作和施行操作,迭代器被分为五类

   input iterator             output iterator
        |                           |
        |                           |
        |___________________________|
                      |
                      |
               forward iterator
                      |
                      |
            bidirectional iterator
                      |
                      |
            random access iterator

上述箭头不是继承的关系,而是concept和refinement的关系

以advance为例,我们可以在运行时根据不同的类型,调用不同的advance函数,但这样影响效率,选择不同函数版本可以在编译器解决,只要增加tag就行

五个标记用的型别

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 {};

这些classes只作为标记用,所以为空,通过继承,我们可以少写一些重载函数

每个新设计的iterator应该提供这五个内嵌型别,不然可能无法与STL其他组件搭配,所以STL提供了一个iterator class如下,每个新设计的迭代器都继承自它,就可保证符合STL所需之规范

template <class Category,
          class T,
          class Distance  = ptrdiff_t,
          class Pointer   = T*,
          class Reference = T&>
struct iterator {
    typedef Category iterator_category;
    typedef T value_type;
    typedef Distance difference_type;
    typedef Pointer pointer;
    typedef Reference reference;
};
template <class Item>
struct ListIter : public iterator<forward_iterator_tag, Item> { /*...*/ };

参考

  • STL源码剖析第三章:迭代器概念与traits编程技法

STL源码阅读-traits与迭代器的更多相关文章

  1. STL源码阅读-functor与adapter

    为什么要用仿函数 函数指针不灵活,难以与STL其他组件配合使用 Adapter 将一个class的接口转换为另一个class的接口,使原本因接口不兼容而不能合作的classes,可以一起运作 STL中 ...

  2. STL源码之traits编程技法

    摘要 主要讨论如何获取迭代器相应型别.使用迭代器时,很可能用到其型别,若需要声明某个迭代器所指对象的型别的变量,该如何解决.方法如下: function template的参数推导机制 例如: tem ...

  3. STL源码分析-iterator(迭代器)

    1. GOF 迭代器设计模式 前面一篇文章有写到stl_list的实现,也实现了一下相应的iterator,但是后面觉得,实现具体容器之前有必要介绍一下iterator(迭代器) .那么迭代器是什么呢 ...

  4. STL源码分析-traits

    http://note.youdao.com/noteshare?id=b5fd9f936cd133af3790a8b0e9c35b8a

  5. [转载]《STL源码剖析》阅读笔记之 迭代器及traits编程技法

    本文从三方面总结迭代器   迭代器的思想   迭代器相应型别及traits思想   __type_traits思想 一 迭代器思想 迭代器的主要思想源于迭代器模式,其定义如下:提供一种方法,使之能够依 ...

  6. 【STL 源码剖析】浅谈 STL 迭代器与 traits 编程技法

    大家好,我是小贺. 点赞再看,养成习惯 文章每周持续更新,可以微信搜索「herongwei」第一时间阅读和催更,本文 GitHub : https://github.com/rongweihe/Mor ...

  7. STL源码--iterator和traits编程技法

    第一部分 iterator学习 STL iterators定义: 提供一种方法,使之能够依序巡访某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表达方式. 任何iteartor都应该提供5 ...

  8. STL源码分析《4》----Traits技术

    在 STL 源码中,到处可见 Traits 的身影,其实 Traits 不是一种语法,更确切地说是一种技术. STL库中,有一个函数叫做 advance, 用来将某个迭代器(具有指针行为的一种 cla ...

  9. 《STL源码剖析》学习之traits编程

    侯捷老师在<STL源码剖析>中说到:了解traits编程技术,就像获得“芝麻开门”的口诀一样,从此得以一窥STL源码的奥秘.如此一说,其重要性就不言而喻了.      之前已经介绍过迭代器 ...

随机推荐

  1. Spring MVC整合fastjson、EasyUI乱码问题

    一.框架版本 Spring MVC:spring-webmvc-4.0.0.RELEASE fastjson:fastjson-1.2.45 EasyUI:1.5 二.乱码现象 Controller调 ...

  2. ubuntu安装成功之后需要做些什么?

    1.安装VMtool 1.1打开虚拟机之后-> 安装VMtool 1.2 点击之后,桌面就会出现一个VMtool光驱文件,如果提示光驱被占用就先用root登录 1.3在命令行挂载 sudo mo ...

  3. C++笔记(1)——Anniversary

    世界太喧闹,不如敲代码. 直接上题目: Zhejiang University is about to celebrate her 122th anniversary in 2019. To prep ...

  4. android4.2 webkit 中的jni

    在android 应用开发中使用WebView,当一个webveiw 被创建时, 也会去load 他所对应的动态库,这里动态库也就是传说中的webkit 内核等. C++ 层与java 层的交互也是通 ...

  5. CISCO路由器WAN口动态ISP配置

        Building configuration... version 15.0 service timestamps debug datetime msec service timestamps ...

  6. 【科普杂谈】一文看懂大数据的技术生态圈,Hadoop,hive,spark都有了

    大数据本身是个很宽泛的概念,Hadoop生态圈(或者泛生态圈)基本上都是为了处理超过单机尺度的数据处理而诞生的.你可以把它比作一个厨房所以需要的各种工具.锅碗瓢盆,各有各的用处,互相之间又有重合.你可 ...

  7. vscode配置PHP Debug

    1.先在vscode中安装PHP Debug,在设置添加“php.validate.executablePath”项,选中对应版本的php.exe. "php.validate.execut ...

  8. 再谈js对象数据结构底层实现原理-object array map set

    如果有java基础的同学,可以回顾下<再谈Java数据结构—分析底层实现与应用注意事项>:java把内存分两种:一种是栈内存,另一种是堆内存.基本类型(即int,short,long,by ...

  9. redhat 7 防火墙配置

    没有iptables 用systemctl stop firewalld

  10. HDU 1203 I NEED A OFFER! (动态规划、01背包、概率)

    I NEED A OFFER! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...