iterator_traits( 转)

来源:互联网 发布:java读取zip文件乱码 编辑:程序博客网 时间:2024/06/02 10:30

Reference Type  Pointer Type

所谓左值(lValue):是用来代表某个对象的一个东西。如果p是指向类型为T的某个对象,那么表达式*p不能只是返回类型为T的对象,而必须是返回一个lValue(左值)。

   平时总是拿起*p就直接赋值(对于简单基本类型,例如int *p = &I ;  *p=3),没想什么*p返回左值那么多。但是当在自定义类中重栽*运算符的时候,我们就要特别小心,要注意到这点,返回为T&才对。

言规正传

iterator_traits的某些机制所蕴涵的意义十分微妙而深远,不过它的实现却不是很复杂,不过这些东西看起来比较容易看懂,真正能够灵活使用就需要花时间领悟了,为什么会采取这种方法解决问题,和其它的方法对比有什么好处和提高?这种明白这些问题才算掌握了trait的实质。

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    ;

};

template< class T>

struct iterator_traits

{

typedef   random_access_iterator_tag   iterator_category;

typedef   T        value_type;

typedef   ptrdiff_t    difference_type;

typedef   T*           pointer;

typedef   T&         reference    ;

};

template< class T>

struct iterator_traits

{

typedef   random_access_iterator_tag   iterator_category;

typedef   T        value_type;

typedef   ptrdiff_t    difference_type;

typedef   T*           pointer;

typedef   T&         reference    ;

};

当你定义一个自己的算法,你需要关注这个机制,下面两个理由就是你可能要用到iterator_traits

    你必须返回某值,或者是申明临时变量,而其它型别与iteratorvalue type或者different type或者reference type或者pointer type一致。

    你的算法类似与advance,必须根据iterator的分类来决定不同的实现方法(提高效率,在编译时候进行判断而不是在运行的时候进行判断),没有traits机制,你只好在‘一般化但是没效率’或者‘有效率但是过度狭隘’中进行抉择。

当定义一个Iterator类,就得在改类中定义五个嵌套的类型,如上面的五个所示。要不然就得针对你的Iterator类,明白的令iterator_traitsIterator特化,就像iterator_traits要明白的针对指针而特化一样。第一种做法总是比较简单,尤其是STL的一个辅助类,base class iterator,让事情变得更简单了。

template< class Category,

class Value,

class Distance =ptrdiff_t,

class Pointer = Value*,

class Reference = Value &

>

struct iterator

{

typedef Category iterator_category;

typedef Value      value_type;

typedef Distance difference_type;

typedef Pointer     pointer;

typedef Reference   reference;

};

     为了确保iterator_traits能够对新的iterator class有适当的定义,最简单的方法就是从iterator类派生自己的iterator。基类iterator不含任何成员函数和成员变量,所以继承不存在额外的开销。