准备知识

什么是迭代器?
  • 迭代器是链接容器和算法的桥梁,所有的算法都通过迭代器操作容器中的数据

  • 迭代器是一种智能指针,最重要的操作符重载就是operator*,operator->

  • 迭代器的实现需要知道容器的具体细节,因此每一种容器都对应自己特有的迭代器,但是迭代器的接口是一致的

Traits编程技巧
  • 目的:提取出容器中存放的数据类型

  • 核心是使用模板技术,在编译期就确认需要调用的函数

  • 嵌套从属名称:

template <typename T>
class Data
{
typedef T value_type;
}; template <typename T>
class Type
{
// typename T::value_type 就是一个嵌套从属名称,其中的typename不能掉
// 理解模板类型中使用模板类型
typedef typename T::value_type value_type;
}; int main()
{
Type<Data<int>>::value_type a(); // a()表示一个类型为int的变量
}
占位参数实现函数重载
  • 占位参数是函数参数,只是这种参数只有参数类型,没有参数名

  • 占位参数同样属于参数列表,可以实现重载

// int是占位参数
void print(int)
{
cout << "void print(int)" << endl;
} void print()
{
cout << "void print()" << endl;
} int main()
{
print(); // 调用void print(int)
print(); // 调用void print()
}

源码

常用的迭代器相应类型
  • 一般在迭代器中常用的容器类型一共5种

template <class I>
struct iterator_traits
{
typedef typename I::iterator_category iterator_category;
typedef typename I::value_type value_type;
typedef typename I::difference_type difference_type;
typedef typename I::pointer pointer;
typedef typename I::reference reference
}; /*
value_type:迭代器所指数据类型
difference_type:表示两个迭代器之间距离的类型
reference:数据内容本身类型
pointer:与reference对应的指针类型
iterator_category:
Input Iterator:只读
Output Iterator:只写
Forward Iterator:可读可写,只能前进,每次前进一个单位
Bidirectional Iterator:可读可写,双向移动,每次移动一个单位
Random Access Iterator:可读可写,双向移动,每次移动多个单位
*/
  • 由于原生的指针类型并没有提供者5种类型的定义,因此进行特化处理
// 实现原生指针的类型提取
template <class T>
struct iterator_traits<T*>
{
...
typedef T* pointer;
typedef T& reference;
}; // 实现const指针的类型提取,去掉const属性,因为会通过迭代器操作容器中的数据
template <class T>
struct iterator_traits<const T*>
{
...
typedef const T* pointer;
typedef const T& reference;
};
  • 5种iterator_category的类型定义,都只是类型定义,没有任何成员
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 { };
iterator完整代码
  • 迭代器类型相关代码

// 五种迭代器类型
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 {}; // 定义一个基础类,提供迭代器需要的类型定义,编译继承实现,防止遗漏
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 Iterator>
struct iterator_traits {
typedef typename Iterator::iterator_category iterator_category;
typedef typename Iterator::value_type
typedef typename Iterator::difference_type
typedef typename Iterator::pointer
typedef typename Iterator::reference
}; // 针对原生指针的特化处理
template <class T>
struct iterator_traits<T*> {
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
}; // 针对const指针的特化处理
template <class T>
struct iterator_traits<const T*> {
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef const T* pointer;
typedef const T& reference;
}; // 该函数非常方便的提取某个迭代器的类型iterator_category
template <class Iterator>
inline typename iterator_traits<Iterator>::iterator_category iterator_category(const Iterator&)
{
typedef typename iterator_traits<Iterator>::iterator_category category;
return category();
} // 该函数非常方便的提取某个迭代器的类型difference_type
template <class Iterator>
inline typename iterator_traits<Iterator>::difference_type* distance_type(const Iterator&)
{
return static_cast<typename iterator_traits<Iterator>::difference_type*>();
} // 该函数非常方便的提取某个迭代器的类型value_type
template <class Iterator>
inline typename iterator_traits<Iterator>::value_type* value_type(const Iterator&)
{
return static_cast<typename iterator_traits<Iterator>::value_type*>();
}
  • advance函数
// 迭代器前进
template <class InputIterator, class Distance>
inline void advance(InputIterator& i, Distance n)
{
__advance(i, n, iterator_category(i));
} // radom迭代器前进
template <class RandomAccessIterator, class Distance>
inline void __advance(RandomAccessIterator& i, Distance n, random_access_iterator_tag)
{
i += n;
} // bidirectional迭代器前进
template <class BidirectionalIterator, class Distance>
inline void __advance(BidirectionalIterator& i, Distance n, bidirectional_iterator_tag)
{
if (n >= )
while (n--) ++i;
else
while (n++) --i;
} // input迭代器前进
template <class InputIterator, class Distance>
inline void __advance(InputIterator& i, Distance n, input_iterator_tag)
{
while (n--) ++i;
}
  • distance函数
// 计算迭代器之间的距离
template <class InputIterator>
inline iterator_traits<InputIterator>::difference_type distance(InputIterator first, InputIterator last)
{
typedef typename iterator_traits<InputIterator>::iterator_category category;
return __distance(first, last, category());
} // 计算random迭代器之间的距离
template <class RandomAccessIterator>
inline iterator_traits<RandomAccessIterator>::difference_type __distance(RandomAccessIterator first, RandomAccessIterator last,
random_access_iterator_tag)
{
return last - first;
} // 计算Input迭代器的距离
template <class InputIterator>
inline iterator_traits<InputIterator>::difference_type __distance(InputIterator first, InputIterator last, input_iterator_tag)
{
iterator_traits<InputIterator>::difference_type n = ;
while (first != last)
{
++first;
++n;
}
return n;
}
  • __type_traits技术

    • 不属于标准的STL,属于SGI STL的私有代码

    • 技术和iterator_traits技术相同,只是定义的类型不同,作用场合不同

    • 如POD就是__type_traits中定义的一种类型

    • 部分代码如下:

struct __true_type { };
struct __false_type { }; template <class type>
struct __type_traits
{
typedef __true_type this_dummy_member_must_be_first;
typedef __false_type has_trivial_default_constructor;
typedef __false_type has_trivial_copy_constructor;
typedef __false_type has_trivial_assignment_operator;
typedef __false_type has_trivial_destructor;
typedef __false_type is_POD_type; // 是否是POD类型
}; __STL_TEMPLATE_NULL struct __type_traits<char> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<signed char>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<unsigned char>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
__STL_TEMPLATE_NULL struct __type_traits<short>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
}; // ... 每种基本类型都有定义 // 对原生的指针类型进行定义
template <class T>
struct __type_traits<T*>
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};

STL源码剖析:迭代器的更多相关文章

  1. STL源码剖析 迭代器(iterator)概念与编程技法(三)

    1 STL迭代器原理 1.1  迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型,STL设计的精髓在于,把容器(Containers)和算法(Algorithms)分开,而迭代器(i ...

  2. STL源码剖析--迭代器(转)

    一.为什么需要traits编程技术 前面说了很多关于traits的光荣事迹,但是却一直没有介绍traits究竟是个什么东西,究竟是用来干什么的?traits在英文解释中就是特性,下面将会引入trait ...

  3. STL源码剖析(迭代器)

    在STL中,容器跟算法是分开设计的,算法是通过迭代器来对容器进行操作的. 在算法运用迭代器的时候,可能会用到其相应的型别,例如返回值为容器中元素的型别,又或者说根据迭代器的类型来选择更好的算法等等. ...

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

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

  5. STL"源码"剖析-重点知识总结

    STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...

  6. 【转载】STL"源码"剖析-重点知识总结

    原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点 ...

  7. (原创滴~)STL源码剖析读书总结1——GP和内存管理

    读完侯捷先生的<STL源码剖析>,感觉真如他本人所说的"庖丁解牛,恢恢乎游刃有余",STL底层的实现一览无余,给人一种自己的C++水平又提升了一个level的幻觉,呵呵 ...

  8. STL源码剖析读书笔记之vector

    STL源码剖析读书笔记之vector 1.vector概述 vector是一种序列式容器,我的理解是vector就像数组.但是数组有一个很大的问题就是当我们分配 一个一定大小的数组的时候,起初也许我们 ...

  9. STL"源码"剖析

    STL"源码"剖析-重点知识总结   STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略 ...

  10. 《STL源码剖析》相关面试题总结

    原文链接:http://www.cnblogs.com/raichen/p/5817158.html 一.STL简介 STL提供六大组件,彼此可以组合套用: 容器容器就是各种数据结构,我就不多说,看看 ...

随机推荐

  1. Nginx负载均衡的详细配置 + Keepalived使用

    1,话不多说, 这里我们来说下很重要的负载均衡, 那么什么是负载均衡呢? 由于目前现有网络的各个核心部分随着业务量的提高,访问量和数据流量的快速增长,其处理能力和计算强度也相应地增大,使得单一的服务器 ...

  2. Python3-threading模块-多线程

    什么是线程? 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务 P ...

  3. Python3-内置类型-集合类型

    Python3中的集合类型主要有两种 set 可变集合 可添加和删除元素,它是不可哈希的,因此set对象不能用作字典的键或另一个元素的集合 forzenset 不可变集合 正好与set相反,其内容创建 ...

  4. NFC芯片选型及基本电路框架

    RFID作为一项专业度较高的技术,在一些公司,可能还会专门招聘专业的RFID工程师.本篇阐述的涉及到的只是基本选型设计.电路框架,关于RFID天线调试.低功耗检卡调试等,后续再其他篇章会继续更新! N ...

  5. web 基础(一) HTML

    web 基础(一) HTML 与 XHTML 一.HTML介绍 HTML( Hyper Text Markup Language)指的是超文本标记语言,是用来描述网页的一种语言.它包括一系列标签.通过 ...

  6. SpringBoot中VO,DTO,DO,PO的概念、区别和用处

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/zhuguang10/article/de ...

  7. 【Spring】原来SpringBoot是这样玩的

    菜瓜:我自己去调Mvc的源码差点没给Spring的逻辑秀死...难受 水稻:那今天咱们看一个简单易用的SpringBoot吧 菜瓜:可以,这个我熟悉 水稻:熟悉? 菜瓜:当我没说,请开始你的表演 水稻 ...

  8. 【Spring注解驱动开发】BeanPostProcessor在Spring底层是如何使用的?看完这篇我懂了!!

    写在前面 在<[String注解驱动开发]面试官再问你BeanPostProcessor的执行流程,就把这篇文章甩给他!>一文中,我们详细的介绍了BeanPostProcessor的执行流 ...

  9. 主存到Cache直接映射、全相联映射和组相联映射

    转自:https://blog.csdn.net/dongyanxia1000/article/details/53392315 ---- Cache的容量很小,它保存的内容只是主存内容的一个子集,且 ...

  10. 每日一题 - 剑指 Offer 50. 第一个只出现一次的字符

    题目信息 时间: 2019-07-03 题目链接:Leetcode tag:哈希表 难易程度:简单 题目描述: 在字符串 s 中找出第一个只出现一次的字符.如果没有,返回一个单空格. s 只包含小写字 ...