打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
iterator与iterator

 

   跟据侯捷的《STL源码剖析》一书中提到的《Design Patterns》一书中关于iterator模式定义:提供一种方法,使之能够依序寻访某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表达方式。

  当然,STL的中心思想在于:将数据容器和算法分开,彼此单独设计,最后再以一帖胶着剂将他们撮合在一起。

  迭代器可以看作是一种smart pointer,故要进行内容提领和成员访问,关键的工作就是对operator*和operator->进行重载

//忽略模板类定义T &operator*()const {return *pointee;} //其中T作为模板参数T* operator->() const{return pointee;} //pointee作为已定义成员

  当然iterator的设计中有一条关键的地方就是封装和隐藏,在此不提。

  为了引出STL设计的关键部分——Traits,需提到一个“相应型别”,也就是迭代其所指之物的类型。

  在c++中只有sizeof()和RTTI中的typeid(),前者只能判断出类型大小,无法进行类型确定,后者由于得到的只是一种别名(vs环境下为全程,MinGW下只是开头字母例如“int”中的‘i’。)况且后者属于运行期判断,不仅需要virutal而且判断期靠后因此不能拿来使用。

  我们在这里需要的并不是输出一个类型的名称,而是在调用过程中间接使用,将其隐藏起来。因此使用模板的类型推断是个不错的做法。

  迭代器相应型别最常用的有五种,分别是value_type,difference_type,reference,pointer,iterator_category。

  这里我们为了下面的Iterator_Traits技术需要提到一下模板偏特化问题。

例如:

templatestruct test{typedef T value_type;T *pointer;};template //偏特化struct test{typedef T value_type;}    

 偏特化的定义:针对任何template参数更进一步的条件限制所设计出来的一个特化版本。

 我们需要考虑的偏特化情形有如下情况:

 1.原始指针

 2 .const T * 

 之所以进行以下两种特化,主要愿意是1.原始指针无法进行内置型别的定义,也就是说无法进行typedef操作,故对以后的过滤会造成很大的麻烦,而且原始指针不能够被忽略。2.对于const T*来说,不能够被轻易修改,而且如果不另外考虑,也会造成不必要的麻烦。

可对照一下代码

//原模板templatestruct test{ typedef T value_type;};
//原始指针特化templatestruct test{typedef T value_type;};
//const pointertemplatestruct test{typedef T value_type;};

  这样,我们不管是调用哪个,都会有一个value_type,而这个value_type到底是何方神圣,已经被我们隐藏起来了。

  我们可以依照上述例子描述difference_type,pointer,reference。但是difference_type可以typedef库中的ptrdiff_t,来实现。

  至此,我们只剩下了iterator_category这一个类型了。

  iterator_category作为一个指针移动的特性和实行操作,我们有如下五类:

 Input Iterator  Output Interator  Forward Iterator  Bidirectional Iterator  Random Access Iterator

其中 input 和output这两种属于访问权限修饰,其他的三种依次深入,我们可以从下面代码中看出

struct input_iterator{}; //只读struct output_iterator{};  //只写struct forward_iterator:public input_iterator{};    //写入型,单项型操作struct bidirectional_iterator:public forward_iterator{}; //可双向移动struct random_access_iterator:public bidirectional_iterator{}; //可进行跳跃访问,涵盖所有指针的运算能力

  c++中的多态性中有一个重载的概念,也就是说有如下例子

#include
using namespace std;
class base{//empty};class deriver:public base{//empty};void test(base &){//empty;}
int main()
{
base b;
deriver d;
test(b); //ok
test(d); //ok
}

 这样,我们就可以写更少的函数来实现我们需要的所有方法

  好,为了使上述居多的描述更加清晰可见,思路更加清晰,上一大段代码进行分析

  

#includeusing namespace std;struct input_iterator{};struct output_iterator{};struct forward_iterator:public input_iterator{};struct bidirectional_iterator:forward_iterator{};struct random_access_iterator:bidirectional_iterator{};templatestruct iterator{ typedef Category iterator_category; typedef T value_type; typedef Pointer pointer; typedef Reference reference; typedef Distance difference_type;};templatestruct Iterator_traitss{ typedef typename Iterator::iterator_catergory iterator_category; typedef typename Iterator::value_type value_type; typedef typename Iterator::pointer pointer; typedef typename Iterator::reference      reference; typedef typename Iterator::difference_type difference_type;};templatestruct iterator_traitss{ typedef random_access_iterator               iterator_category; typedef T value_type; typedef ptrdiff_t     difference_type; typedef T* pointer; typedef T& reference;};templatestruct iterator_traitss{ typedef random_access_iterator          iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef const T* pointer; typedef const T& reference;};templateinline typename iterator_traits::iterator_category iterator_category(const Iterator&){ typedef typename iterator_traitss::iterator_category category; return category();}int main(){}

  

   通过上述代码我们可以清晰看到,有一个iterator类模板,我们在其中的模板参数除了第一个参数外,其他的都有默认值,这个和我们现在使用的vector等其中的Iterator是一致的 。

  有了iterator模板后,我们需要一个强有劲的过滤器,那就是iterator_traits,这个可以将模板参数不管是什么样的,统统封装成统一的typedef,例如 value_type的形成。

  这样我们就可以很方便的进行下面的操作。请注意在iterator_traits中T*的特化还有const T*的特化那里,iterator_category的原名是random_access_iterator.

  总结:

     我们可以通过typedef机制,隐藏,集中一类特性。

     我们可以通过模板参数推导机制,针对同一别名的不同类型进行不同操作。为了效率因素,进行编译期多态而非运行期多态。

 

 

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
全特化/偏特化
C++模板之特化与偏特化详解
boost源码剖析之:泛型编程精灵type_traits
<转载>独一无二的C++模板
【STL 源码剖析】浅谈 STL 迭代器与 traits 编程技法
<STL源码剖析>阅读笔记之 仿函数和适配器
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服