千张笔记

Email:rain_qian830@163.com
posts - 28, comments - 42, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

【原】Iterator浅析(Input Iterator)

Posted on 2009-02-25 23:00 千张 阅读(2163) 评论(0)  编辑 收藏 引用 所属分类: C++/VS.NET

读<泛型编程与STL>第二章

所谓concept,是一组“描述某个型别”的条件。当某个型别满足所有这样的条件,我们便说它是该concept的一个model。举例来说,char* 便是Input Iterator的model。

concept并不是类,变量或是template参数,事实上它不是可以直接在C++程序中呈现的东西。然而在每个运用"泛型编程(generic programming)"的C++程序中,concept非常重要。也就是说concept不像class,int那样有一个明确的关键字,可以在程序中直接声明其对象的,它只是一组条件,作为一个concept的model,它必须满足这个concept的所有条件。

Iterator是指针的概括物,它们是"用来指向其他对象"的一种对象,这对于像find这样的泛型算法很重要,因为他们可以用来在对象区间内"来回移动(iterate)"。

Iterator对于泛型编程之所以重要,原因是它是算法与数据结构之间的接口。类似find这样的算法,以iterator为引数,便可以作用在许许多多不同的数据结构上-即使彼此结构不同(例如链表与C数组)。我们仅仅要求:iterator能够以某种线性顺序遍历某个数据结构,以访问其中所有的元素。

Iterator不单单只是一个concept,而是五个不同的concepts:Input Iterator,Output Iterator,Forward Iterator,Bidirectional Iterator和Random Access Iterator。

<一> Input Iterator
本质上,Input Iterator是某种类似指针的东西,并且在我们谈到iterator range[first,last)时有意义:
1.当它作为一般的C指针时,有三种价值:它是dereferenceable(可取值的),past the end(可跨越尾端的),singular(可为null的)。当它作为指针,只有在first和last都不为null指针时,[first,last)才是有意义的range。

2.我们可以比较型别为Iterator的两个对象的相等性。例如:while(first!=last)。

3.Input Iterator可以被复制或被赋值。在调用一个函数时,可以用传值的方式传入参数,如find的参数first和last就是两个Iterator,可以用传值来传入参数,这会掉用Iterator的copy constructor。

4.可以提领(dereference)一个型别为Iterator的对象。也就是说,表达式*p有充分的定义。每一个Input Iterator都有一个associated value type,那是它所指的对象的型别。

5.可以对一个型别为Iterator的对象进行累加动作。也就是说,表达式++p和p++都有充分定义。

注意:
1.Input Iterator用来指向某对象,但不需要提供任何更改该对象的方法。可以提领一个Input Iterator,但不能对提领后的结果赋予新值,也就是说表达式*p=x不一定有效。

2.Input Iterator可以累加,但并非一定需要递减。Input Iterator唯一需要的运算形式是operator++。

3.可以测试两个Input Iterator是否相等,但不能测试谁在谁之前。也就是说p1<p2不一定成立(p1,p2都是Input Iterator)。

4.Input Iterator的唯一正确使用方式是线性查找,这是一种"single pass(单回)"算法,它只遍历range[first,last)一次,并对range中的值最多读取一次。也就是说,遍历时只能像前(++),不能退后,前一个遍历的值不再有效。不能以两个iterator指向"由Input iterator形成的range"中的两个不同元素。

举例:
1.template<class InputIterator, class T> inline
     InputIterator find(InputIterator first, InputIterator last, const T& value)
上面为泛型算法find的定义,可以看见find的前两个参数都为InputIterator类型的Iterator。
sample如下:


#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    int size = 8;
    vector<int> vec(size);
    vector<int>::iterator iter = vec.begin();
    for(int ix = 0; iter != vec.end(); ++iter,++ix)
        *iter = ix;
   
    cout << "Array = { ";
    for(vector<int>::iterator iter2 = vec.begin(); iter2 != vec.end(); ++iter2)
        cout << *iter2 <<",";
    cout << "}" << endl;

    vector<int>::iterator location;
    int value = 7;
    location = find(vec.begin(),vec.end(),value);
    if(location != vec.begin() + vec.size())
        cout << "First element that matches " << value << " is at location " << location - vec.begin() << endl;
    else
        cout << "The sequence doesn't contain any elements with value " << value << endl;
   
    return 0;
}

MSDN中定义
vector::iterator
typedef T0 iterator; 说明iterator是vector中的一个型别,它是T0的别名,至于T0是在哪里定义的,可以参考vc98目录下Include中的VECTOR文件,定义如下:(注意此定义与MSDN中的定义的区别
///////////////////////////////////////////////////////////////////////////////////////
.......
template<class _Ty, class _A = allocator<_Ty> >
 class vector {
public:
 typedef vector<_Ty, _A> _Myt;
 typedef _A allocator_type;
 typedef _A::size_type size_type;
 typedef _A::difference_type difference_type;
 typedef _A::pointer _Tptr;
 typedef _A::const_pointer _Ctptr;
 typedef _A::reference reference;
 typedef _A::const_reference const_reference;
 typedef _A::value_type value_type;
 typedef _Tptr iterator;         //MSDN中此处_Tptr换成了T0,可知iterator是一个指针类型
 typedef _Ctptr const_iterator;
//////////////////////////////////////////////////////////////////////////////////////////

在MSDN中有如下说明:
The object allocates and frees storage for the sequence it controls through a protected object named allocator, of class A. Such an allocator object must have the same external interface as an object of template class allocator.
而class allocator_object中是这样说明pointer的:
pointer -- behaves like a pointer to T
所以iterator是一个指向T类型的指针,在本sample中,T是int类型,故iterator是int类型的指针。

2.istream_Iterator
istream_Iterator是一种Input Iterator。sample如下:
//输入--排序--输出
#include <iostream>
#include <string> 
#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;

int main()
{
     vector<int> V;
    cout << "请输入整数序列,按任意非数字键并回车结束输入: \n";
    copy(istream_iterator<int>(cin),istream_iterator<int>(),back_inserter(V));
    cout << "排序中......" << endl;
    sort(V.begin(),V.end());
    cout << "下面显示经过排序的序列: \n";
    copy(V.begin(),V.end(),ostream_iterator<int>(cout," "));
    cout << endl;
    return 0;
}
代码具体解释可参考Clare的blog:
http://www.cnblogs.com/oomusou/archive/2006/12/07/585123.html

 

 


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理