如何定义自己的迭代器
2006-09-24 15:12
302 查看
[align=left]基本上iterator必须做两件事情
1)必须指向某物
2)他必须能够遍历任何一个有效区间。一旦定义了operator* operator++通常剩下的行为就比较简单了。
必须确定iterator被正确的定义为constant或者mutable。这是常犯的错误之一。不过input iterator不在乎这一点,因为具有只读性。outputIterator具有只写性。
对于其他的类型的iterator就不一样了[/align]
[align=left]定义自己的Iterator时,必须定义五个嵌套类型,iterator_category、value_type、difference_type、pointer和reference。[/align]
[align=left]STL含有一个辅助类,base class iterator,[/align]
[align=left]An empty base class that provides types and that may be used to ensure that a user-defines iterator class works properly with iterator_traits.[/align]
[align=left]template<class Category, class Type, class Distance = ptrdiff_t[/align]
[align=left] class Pointer = Type*, class Reference = Type&>[/align]
[align=left] struct iterator {[/align]
[align=left] typedef Category iterator_category;[/align]
[align=left] typedef Type value_type;[/align]
[align=left] typedef Distance difference_type;[/align]
[align=left] typedef Pointer pointer;[/align]
[align=left] typedef Reference reference;[/align]
[align=left] };[/align]
[align=left]Remarks[/align]
[align=left]The template class serves as a base type for all iterators. It defines the member types[/align]
iterator_category (a synonym for the template parameter Category).
value_type (a synonym for the template parameter Type).
difference_type (a synonym for the template parameter Distance).
pointer (a synonym for the template parameter Pointer).
reference (a synonym for the template parameter Reference).
[align=left]Note that value_type should not be a constant type even if pointer points at an object of const Type and reference designates an object of const Type.[/align]
下面是一个iterator的完整定义和使用
[align=left]#include "stdafx.h"[/align]
[align=left]#include <iterator>[/align]
[align=left]using namespace std;[/align]
[align=left]//下面函数主要来定义迭代器,一个专门针对还含有next的铁代器[/align]
[align=left]template <typename Node, typename Reference = Node&, typename Pointer = Node*>[/align]
[align=left]struct node_wrap_base_iterator:public iterator<forward_iterator_tag,Node,ptrdiff_t,Pointer,Reference>[/align]
[align=left]{[/align]
[align=left] typedef node_wrap_base_iterator<Node,Node&,Node*> iterator;[/align]
[align=left] typedef node_wrap_base_iterator<Node,const Node&,const Node*> const_iterator;[/align]
[align=left] Pointer ptr;[/align]
[align=left] node_wrap_base_iterator(Pointer p = 0):ptr(p){}[/align]
[align=left] node_wrap_base_iterator(const iterator& x):ptr(x.ptr){}[/align]
[align=left] Reference operator*()const{return *ptr;}[/align]
[align=left] Pointer operator->()const{return ptr;}[/align]
[align=left] void incr(){ptr=ptr->next;}[/align]
[align=left] node_wrap_base_iterator& operator++(){incr(); return *this;}[/align]
[align=left] node_wrap_base_iterator operator++(int){node_wrap_base_iterator tmp=*this;incr();return tmp;}[/align]
[align=left] bool operator==(const node_wrap_base_iterator& x) const {return ptr==x.ptr;}[/align]
[align=left] bool operator!=(const node_wrap_base_iterator& x) const {return ptr!=x.ptr;}[/align]
[align=left]};[/align]
[align=left][/align]
[align=left]测试:[/align]
typedef struct Node
{
int value;
Node* next;
}Node;
//重载<<
ostream& operator<<(ostream & out,Node node)
{
out<<node.value;
return out;
}
//使用迭代器
template<typename iterator>
void display(iterator begin,iterator end)
{
iterator tmp = begin;
while(tmp!=end&&tmp!=NULL)
{
cout<<*tmp<<" ";
tmp++;
}
cout<<endl;
}
template <typename Iterator>
//学习使用iterator_traits
typename iterator_traits<Iterator>::value_type test_traits(Iterator iter)
{
return *iter;
}
#define N 10
typedef node_wrap_base_iterator<Node>::iterator node_iterator;
int _tmain(int argc, _TCHAR* argv[])
{
Node node
;
for(int i=0; i<N;i++)
{
node[i].value=i;
if(i < N-1)
node[i].next=&node[i+1];
else
node[i].next=NULL;
}
node_iterator beg(node);
node_iterator end(node+N);
display(beg,end);
Node test;
test.value=11;
test.next=NULL;
node_iterator iter(&test);
cout<<test_traits(iter);
cout<<endl;
return 0;
}
1)必须指向某物
2)他必须能够遍历任何一个有效区间。一旦定义了operator* operator++通常剩下的行为就比较简单了。
必须确定iterator被正确的定义为constant或者mutable。这是常犯的错误之一。不过input iterator不在乎这一点,因为具有只读性。outputIterator具有只写性。
对于其他的类型的iterator就不一样了[/align]
[align=left]定义自己的Iterator时,必须定义五个嵌套类型,iterator_category、value_type、difference_type、pointer和reference。[/align]
[align=left]STL含有一个辅助类,base class iterator,[/align]
[align=left]An empty base class that provides types and that may be used to ensure that a user-defines iterator class works properly with iterator_traits.[/align]
[align=left]template<class Category, class Type, class Distance = ptrdiff_t[/align]
[align=left] class Pointer = Type*, class Reference = Type&>[/align]
[align=left] struct iterator {[/align]
[align=left] typedef Category iterator_category;[/align]
[align=left] typedef Type value_type;[/align]
[align=left] typedef Distance difference_type;[/align]
[align=left] typedef Pointer pointer;[/align]
[align=left] typedef Reference reference;[/align]
[align=left] };[/align]
[align=left]Remarks[/align]
[align=left]The template class serves as a base type for all iterators. It defines the member types[/align]
iterator_category (a synonym for the template parameter Category).
value_type (a synonym for the template parameter Type).
difference_type (a synonym for the template parameter Distance).
pointer (a synonym for the template parameter Pointer).
reference (a synonym for the template parameter Reference).
[align=left]Note that value_type should not be a constant type even if pointer points at an object of const Type and reference designates an object of const Type.[/align]
下面是一个iterator的完整定义和使用
[align=left]#include "stdafx.h"[/align]
[align=left]#include <iterator>[/align]
[align=left]using namespace std;[/align]
[align=left]//下面函数主要来定义迭代器,一个专门针对还含有next的铁代器[/align]
[align=left]template <typename Node, typename Reference = Node&, typename Pointer = Node*>[/align]
[align=left]struct node_wrap_base_iterator:public iterator<forward_iterator_tag,Node,ptrdiff_t,Pointer,Reference>[/align]
[align=left]{[/align]
[align=left] typedef node_wrap_base_iterator<Node,Node&,Node*> iterator;[/align]
[align=left] typedef node_wrap_base_iterator<Node,const Node&,const Node*> const_iterator;[/align]
[align=left] Pointer ptr;[/align]
[align=left] node_wrap_base_iterator(Pointer p = 0):ptr(p){}[/align]
[align=left] node_wrap_base_iterator(const iterator& x):ptr(x.ptr){}[/align]
[align=left] Reference operator*()const{return *ptr;}[/align]
[align=left] Pointer operator->()const{return ptr;}[/align]
[align=left] void incr(){ptr=ptr->next;}[/align]
[align=left] node_wrap_base_iterator& operator++(){incr(); return *this;}[/align]
[align=left] node_wrap_base_iterator operator++(int){node_wrap_base_iterator tmp=*this;incr();return tmp;}[/align]
[align=left] bool operator==(const node_wrap_base_iterator& x) const {return ptr==x.ptr;}[/align]
[align=left] bool operator!=(const node_wrap_base_iterator& x) const {return ptr!=x.ptr;}[/align]
[align=left]};[/align]
[align=left][/align]
[align=left]测试:[/align]
typedef struct Node
{
int value;
Node* next;
}Node;
//重载<<
ostream& operator<<(ostream & out,Node node)
{
out<<node.value;
return out;
}
//使用迭代器
template<typename iterator>
void display(iterator begin,iterator end)
{
iterator tmp = begin;
while(tmp!=end&&tmp!=NULL)
{
cout<<*tmp<<" ";
tmp++;
}
cout<<endl;
}
template <typename Iterator>
//学习使用iterator_traits
typename iterator_traits<Iterator>::value_type test_traits(Iterator iter)
{
return *iter;
}
#define N 10
typedef node_wrap_base_iterator<Node>::iterator node_iterator;
int _tmain(int argc, _TCHAR* argv[])
{
Node node
;
for(int i=0; i<N;i++)
{
node[i].value=i;
if(i < N-1)
node[i].next=&node[i+1];
else
node[i].next=NULL;
}
node_iterator beg(node);
node_iterator end(node+N);
display(beg,end);
Node test;
test.value=11;
test.next=NULL;
node_iterator iter(&test);
cout<<test_traits(iter);
cout<<endl;
return 0;
}
相关文章推荐
- 教你如何使用Struts2拦截器并且定义自己的拦截器
- 如何使用Arrays.sort()对自己定义的类进行排序
- 如何定义一个自己的可复用的JS文件
- 如何在Cruise中显示自己定义的report (将EMMA的report显示在页面上)
- 如何通过序列化在网络间传递对象,网络协议:轻松定义自己的网络通讯协议
- 如何定义自己的控件
- 【JTharness4_4_0】【6.如何定义自己的Interview】
- 【cocos2dx】如何创建自己定义的精灵类Sprite
- 自定义View如何定义和使用自己的属性
- nrf51822如何让自己定义的服务也被识别为有意义的名称,如Battery Service?
- java如何定义自己的类
- 如何将自己的实体类封装到一个list中,定义自己一系列的方法
- 如何定义你自己的JavaScript类
- 如何用java按需定制自己的迭代器
- 如何定义自己的ViewGroup
- 如何定义自己的线程函数与第三方系统兼容
- JAVA架构师必知之事 —— 如何定义自己的职业路线?
- JavaScript如何定义一个自己的可复用的JS文件!
- rcp(插件开发) 如何查找自己定义的扩展点
- 如何在博客园上面显示自己定义的头像--【sky原创】