摘要

迭代器是一种行为类似指针的对象,本文介绍iterator与traits的关系,以及对traits内容的补充。包含stl_iterator.h的部分内容,并用c++11对其进行略微改写。

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

接下来是iterator的定义:

//自造的iterator最好继承下面的std::iterator
template<typename Category, typename T,
typename Distance = ptrdiff_t,
typename Pointer = T*,
typename Reference = T&>
struct iterator
{
using iterator_category = Category;
using value_type = T;
using difference_type = Distance;
using pointer = Pointer;
using reference = Reference;
}; //萃取机Traits
//萃取出迭代器的特性
template<typename Iterator>
struct iterator_traits
{
using iterator_category = typename Iterator::iterator_category;
using value_type = typename Iterator::value_type;
using difference_type = typename Iterator::difference_type;
using pointer = typename Iterator::pointer;
using reference = typename Iterator::reference;
};
//针对原生指针的片特化版本
template<typename T>
struct iterator_traits<T*>
{
using iterator_category = random_access_iterator_tag;
using value_type = T;
using difference_type = ptrdiff_t;
using pointer = T*;
using reference = T&;
};
//pointer-to-const
template<typename T>
struct iterator_traits<const T*>
{
using iterator_category = random_access_iterator_tag;
using value_type = T;
using difference_type = ptrdiff_t;
using pointer = const T*;
using reference = const T&;
};
//确定某个迭代器类型,并返回该类型的一个迭代器对象,方便进行函数重载
template<typename Iterator>
inline typename iterator_traits<Iterator>::iterator_category
iterator_category(const Iterator&)
{
using category = typename iterator_traits<Iterator>::iterator_category;
return category();
}
//确定某个迭代器的distance type
template<typename Iterator>
inline typename iterator_traits<Iterator>::difference_type*
distance_type(const Iterator&)
{
return static_cast<typename iterator_traits<Iterator>::difference_type*>(nullptr);
}
//确定某个迭代器的value type
template<typename Iterator>
inline typename iterator_traits<Iterator>::value_type*
value_type(const Iterator&)
{
return static_cast<typename iterator_traits<Iterator>::value_type*>(nullptr);
} //整个distance函数的实现,第三个参数只是激活重载机制,无其他用处
template<typename InputIterator>
inline typename iterator_traits<InputIterator>::difference_type
_distance(InputIterator first, InputIterator last, input_iterator_tag)
{
typename iterator_traits<InputIterator>::difference_type n = 0;
while(first != last)
{
++first;
++n;
}
} template<typename RandomAccessIterator>
inline typename iterator_traits<RandomAccessIterator>::difference_type
_distance(RandomAccessIterator first, RandomAccessIterator last, random_access_iterator_tag)
{
return last - first;
}
//对外接口,适应不同类型的迭代器
template<typename InputIterator>
inline typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last)
{
//先利用traits确定迭代器的类型
using category = typename iterator_traits<InputIterator>::iterator_category;
//利用函数重载,第三个参数只是激活重载机制,无其他用处
_distance(first, last, category());
} //整个advance函数的实现,第三个参数只是激活重载机制,无其他用处
template<typename InputerIterator, typename Distance>
inline void _advance(InputerIterator& i, Distance n, input_iterator_tag)
{
while(n--) ++i;
} template<typename BidirectionalIterator, typename Distance>
inline void _advance(BidirectionalIterator i, Distance n, bidirectional_iterator_tag)
{
if(n >= 0)
while(n--) ++i;
else
while(n++) --i;
} template<typename RandomAccessIterator, typename Distacne>
inline void _advance(RandomAccessIterator& i, Distacne n, random_access_iterator_tag)
{
i += n;
} //对外接口,适应不同类型的迭代器
template<typename InputIterator, typename Distance>
inline void advance(InputIterator& i , Distance n)
{
_advance(i, n, iterator_category(i));
} #endif //STL_ITERATOR_H

最新文章

  1. Entity Framework Plus 系列目录
  2. 第15章 .NET中的反射
  3. Linux 文件常见类型
  4. ubuntu中安装VMWare tools
  5. js中replace的用法【转】
  6. information_schema.partitions 学习
  7. 基于jdk调用天气服务案例及问题
  8. 安装pybloomfiltermmap 遇到bug
  9. 分区工具fdisk,gdisk,parted
  10. 【后缀数组】洛谷P3809模板题
  11. linkin大话面向对象--闭包和回调
  12. SecureCRT通过SSH2协议远程登录Ubuntu 18.04的过程总结
  13. 理解OpenShift(7):基于 Prometheus 的集群监控
  14. 商家服务无法上架提示没有授权信息解决FAQ
  15. 网络编程-TCP/IP
  16. mysql 案例 ~超时时间设置
  17. C语言--第八周作业评分(5班)
  18. [JavaScript] 的异步编程之手写一个Gernerator的例子
  19. Health Endpoint Monitoring模式
  20. VS 2013 无法启动IIS Express Web 服务器

热门文章

  1. Windows GUI自动化测试技术的比较和展望
  2. firstResponder
  3. Java检查异常、非检查异常、运行时异常、非运行时异常的区别
  4. File upload - Double extensions
  5. 使用jpillora/dnsmasq 提供可视化管理的dns server
  6. python 虚拟环境指定python版本
  7. xargs 命令教程
  8. Phoenix概述
  9. 用Python自动办公,做职场高手(完结)
  10. git推送本地分支到远程仓库并在远程仓库创建新分支