自定义一个简单的迭代器(line_iterator)

STL是容器、迭代器、算法三位一体的好东西,使用STL编写的程序看起来非常简洁。比如从cin输入若干字符串,每一字符串占一行,然后将这些字符串按字典序排序并输出到cout中,相关的代码如下所示:

/* 迭代器的使用
 * created: ume
 * date: 2011-12-17
 *
 */
#include<iostream>
#include<vector>
#include<string>
#include<iterator>
#include<algorithm>
using namespace std;
int main()
{
    vector<string> v;
    string temp;
    while(getline(cin,temp))
    {
        v.push_back(temp);
    }
    sort(v.begin(),v.end());
    copy(v.begin(),v.end(),ostream_iterator<string>(cout," "));
    system("pause");
    return 0;
}

包含的头文件非常:

主函数中用到cin/cout以及getline,因此必须包含iostream;

主函数中用到vector<string>,因此必须包含vector和string;

主函数中用到ostream_iterator,因此必须包含iterator;

主函数还调用了sort和copy函数,因此必须包含algorithm。

除了iostream外,其它头文件都是STL头文件。vector和string是容器,iterator是迭代器,algorithm是算法。

编译运行此程序,结果如下所示:

you
are
the
apple
of
my
eye
^Z
apple are eye my of the you 请按任意键继续. . .

如果想倒过来排,只要在把sort(v.begin(),v.end())改写成sort(v.begin(),sort.end(),greater<string>())即可。

现在我们提出一个稍微高一点的要求,上面的程序不是将cout包装到迭代器里了吗,能不能将cin也包装到迭代器里面呢?当然是可以,我们定义一个类来实现:

/* line_iterator.h
 * created: ume
 * date: 2011-12-17
 *
 */
class line_iterator
{
    istream* in;
    string line;
    bool is_valid;
    void read()
    {
        if(*in)
            getline(*in,line);
        is_valid = (*in) ? true : false;
    }

public:
    typedef input_iterator_tag iterator_category;
    typedef string value_type;
    typedef ptrdiff_t difference_type;
    typedef const string* pointer;
    typedef const string& reference;

    reference operator*()
    {
        return line;
    }
    pointer operator->()
    {
        return &line;
    }
    line_iterator():in(&cin),is_valid(false)
    {
    }
    line_iterator(istream& s):in(&s)
    {
        read();
    }
    line_iterator operator++()
    {
        read();
        return *this;
    }
    line_iterator operator++(int)
    {
        line_iterator temp = *this;
        read();
        return temp;
    }
    bool operator==(const line_iterator& rhs)
    {
        if(in == rhs.in && is_valid == rhs.is_valid)
            return true;
        if(is_valid == false && rhs.is_valid == false)
            return true;
        return false;
    }
    bool operator!= (const line_iterator& rhs)
    {
        return !(*this == rhs);
    }
};

代码比较长,看似很复杂,在解释它之前先看看它怎么使用:

/* 迭代器的使用 版本2
 * created: ume
 * date: 2011-12-17
 *
 */
#include<iostream>
#include<vector>
#include<string>
#include<iterator>
#include<algorithm>
using namespace std;
#include"line_iterator.h"
int main()
{
    line_iterator iter(cin);
    line_iterator end_of_file;
    vector<string> v(iter,end_of_file);
    sort(v.begin(),v.end());
    copy(v.begin(),v.end(),ostream_iterator<string>(cout," "));
    system("pause");
    return 0;
}

毫不意外,运行这个新版的程序,结果与旧程序是一样的。比较起来,新版的程序中看不到明显地输入语句。显然这是我们自定义的line_iterator带来的妙处。

新程序中的输入是在哪里实现的呢?请看vector<string> v(iter,end_of_file),用迭代器区间来构造vector,在这个构造方法内部隐含的一定有一个while循环,就是将字符串从iter开始到end_of_file一个接一个的拷贝到vector v中。必然的,它将调用line_iterator的operator++、operator!=等操作符方法。而end_of_file看起来不跟任何变量相关,但是回头看line_iterator的无参构造方法,你会发现它实际上还是跟标准输入cin挂上了钩。所以,在判断有没有到达输入的尾端时,将比较is_valid标记。

line_iterator定义内部的其它成员同样不可或缺,那些看似没用的typedef,实际在于vector以及sort、copy等联合工作的时候被频繁使用到。想要搞懂它们就需要对iterator进行更深一步的学习了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值