迭代器的分类
标准库中的算法都是函数模版
- 算法的两个版本,第三个参数要传递一个准则,仿函数
迭代器的分类
5种迭代器的分类:有继承的关系
- 输入迭代器
- 输出迭代器
- 双向迭代器
- 随机访问迭代器
- 输出迭代器
打印容器迭代器的类型
- 产生的是临时对象
- 使用了模版函数 + 迭代器萃取 traits
- 最后两个特殊的迭代器
迭代器的typeid
- typeid取决于编译器的实现
typeid
#include <typeinfo>
cout << typeid(vector<int>::iterator).name() << endl;
cout 和 cin 的 iterator
gnuc4.9的继承关系是为了继承typedef,没有额外的开销。
迭代器分类对算法的影响
算法需要知道迭代器是何种类型的。
eg1.distance 算法,求两个指针之间的距离
- input迭代器 vs 随机访问迭代器
- 对外界返回的类型是什么? 通过类型萃取得出 difference type。
- 迭代器有五个特性,其中有一个就是difference type
- 通过类型萃取获取迭代器的类型,并且通过这个类型创建一个临时对象传给__distance 调用两个版本
- 如果距离很大的话,效率差别有多大? O(n) vs O(1)
- 使用有继承关系的对象来表现,is-a 关系。一定会落在某个版本中 2个版本,4种分类
eg2. advance
基础算法,效率很重要
- 迭代器是什么类型
- 单向迭代器,只能向前
- 双向迭代器,向前/向后
- 随机迭代器,直接+偏移量
- 根据迭代器类型从上面3中函数中选择
- 将迭代器类型萃取封装成了一个小函数
- 使用有继承关系的对象来表现,is-a 关系
template <typename Iterator>
inline typename iterator_traits<Iterator>::iterator_category
iterator_category(const Iteraotr &)
{
typedef typename iterator_traits<Iterator>::iterator_category category;
return category(); // 返回临时对象
}
eg3. copy 函数
- 泛化 generalization
- 特化 specialization
- 强化 refinement
通过类型萃取判断迭代器是否属于某种特定类型,提供特定的实现(效率高)
- const char* , memmove 底层函数,动作极快
- const wchar_t* memmove
- 泛化的函数继续检查类型
- 泛化 继续检查
- random access 迭代器?last - first > n
- for - loop 相对较慢 first !=last
- <T* , T*> 对指针的操作,拷贝赋值
- 是否重要,不重要的话不调用拷贝赋值函数
- <const T*, const T *>
- 是否重要,不重要的话不调用拷贝赋值函数
- 泛化 继续检查
- type traits 类型萃取
- 复数类不需要提供拷贝构造,拷贝赋值,析构函数等… 对应着不重要
- string类需要。。。 对应着重要
eg4 destroy 类型萃取
*eg5 unique_copy
排序元素去重拷贝
- 针对output-iterator, 实现的版本中避免了read操作