C++ 中Traits技术 (5) —— 关于STL中对迭代器封装的类型介绍
来源:互联网 发布:判断在数组里面 php 编辑:程序博客网 时间:2024/05/20 03:08
上一篇讲到traits的类型萃取,可将迭代器相关的类型获取用于变量声明和函数返回等操作。对于原生指针和const指针可以采用偏特化技术进行处理。
在STL中,对迭代器除了封装类型信息以外,还有一些其他的信息,这篇文章介绍一下。
STL中,迭代器中的类型包括以下五种:
template <class _Iterator>struct iterator_traits {typedef typename _Iterator::iterator_category iterator_category;typedef typename _Iterator::value_type value_type;typedef typename _Iterator::difference_type difference_type;typedef typename _Iterator::pointer pointer;typedef typename _Iterator::reference reference;};
第一种类型:value_type
这个前面介绍过,就是获取迭代器指向元素的类型。
第二种类型:difference_type
这个用于表示两个迭代器之间的距离,对于某些算法这个类型很有用。
如:
template <class I, class T>typename iterator_traits<I>::difference_type count(I first, I last, const T& value){ typename iterator_traits<I>::difference_type n = 0; for(; first != last; first++) { if(*first == value) n++;}return n;}当然,因为原生指针并没有这个类型信息,需要对其特化。
template <class I>class iterator_traits<I*> { typedef ptrdiff_t difference_type;}template <class I>class iterator_traits<const I*> { typedef ptrdiff_t difference_type;}
其中的ptrdiff_t是一个C++内置类型 【typedef long int ptrdiff_t】
第三种类型:reference
这个类型就是迭代器封装对象的引用,是为了解决对指针进行解引用时返回什么类型对象的问题。
这个类型一般用在*运算符重载,让所有指针有相同的表现形式。
第四种类型:pointer
这个类型就是迭代器封装对象的地址,主要用于->运算符重载。
对于智能指针,我们一般需要重载下面两个运算符:
T& operator*() const { return *ptr; } // T& is reference typeT* operator->() const { return ptr; } // T* is pointer type因此,为了对迭代器和原生指针有一个相同的表现形式,在iterator_traits中加入了:
typedef typename _Iterator::pointer pointer;
typedef typename _Iterator::reference reference;
同样需要对const指针和原生指针特化:
template<class T>struct iterator_traits<T*> { typedef typename T* pointer; typedef typename T& reference;}template<class T>struct iterator_traits<const T*> { typedef typename const T* pointer; typedef typename const T& reference;}
第五种类型:iterator_category
最后一种类型,其作用是按照迭代器的移动特性和能够在该迭代器上实施的操作对迭代器进行分类,主要是为了效率。
STL中的迭代器有五种类型:
单向移动只读迭代器 input iterator
单向移动只写迭代器 output iterator
单向移动读写迭代器 forwarditerator
双向移动读写迭代器 bidirectional iterator
随机访问迭代器 random access iterator
前四种属于单步移动迭代器,最后一种属于双向移动迭代器。
在STL提供的各种算法中,遍历元素需要用到advance()函数,而具体实现时需要根据迭代器的不同类型调用各自类型迭代器的advance()实现。
这种类型判断放在运行时确定效率肯定不高。
因此最好是能够在编译期就确定好函数该调用哪一个。
所以,STL中的实现是这样的:
template <class InputIterator, class Distance>void advance(InputIterator& i, Distance n) { // Forward the correct messages __advance(i, n, type_traits<i>::iterator_category());}
另外,STL为我们提供了一个标准的迭代器壳。
template <class Category,class T,class Distance = ptrdiff_tclass 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;};
避免了一些复杂的typedef声明。
参考:
http://www.cppblog.com/nacci/archive/2005/11/03/911.aspx
在此感谢。
- C++ 中Traits技术 (5) —— 关于STL中对迭代器封装的类型介绍
- STL 中traits 技术的应用
- C++ 中Traits技术 (4) —— 类型推导
- C++ 中Traits技术 (2) —— 与迭代器
- STL中traits原理
- STL源码剖析中 traits的使用
- STL学习笔记——迭代器以及Traits技术
- Traits技术:类型的if-else-then(STL核心技术之一)
- Traits技术:类型的if-else-then(STL核心技术之一)
- C++ 中Traits技术 (3) —— 关于特化和偏特化
- STL中traits编程技法
- 对于C++中traits的简单介绍
- C++ 中Traits技术 (1) —— 初识
- STL的榨汁机——type traits
- C++ 11标准STL中Traits的is_pointer的实现
- STL源码剖析——Traits编程技术
- STL源码剖析——Traits编程技术
- C++traits技术的理解
- Android API Guides---Spelling Checker Framework
- 巩固C语言(十二)----文件加解密
- Java Set简单用法
- 吐槽TI的失败设计—cc2640的oad
- Android 编码规范
- C++ 中Traits技术 (5) —— 关于STL中对迭代器封装的类型介绍
- Python Mixin编程机制
- 专题二 1013
- 搜索与机器学习
- 双向循环链表(创建·插入·删除·遍历)
- Swift中文教程(六)函数
- Linux驱动开发-15、网络设备驱动
- SharePoint 轻量化应用之HR招聘系统之初试结果通知及复试面试通知表单
- CSS滤镜