C++中istream_iterator和ostream_iterator的用法

写在前面

今天在看《STL源码剖析》的时候,看到了配接器中的ostream iterator,其中包含istream_iterator以及ostream_iterator以及更多,感觉这两个都十分重要,所以在这里介绍一下

istream_iterator

源码:

template  
class istream_iterator {friend booloperator== __STL_NULL_TMPL_ARGS (const istream_iterator& x,const istream_iterator& y);
protected:istream* stream;T value;bool end_marker;                                 //判断是否读入结束符,比如C语言中的EOF等等void read() {                                    //其中调用的读取函数end_marker = (*stream) ? true : false;if (end_marker) *stream >> value;              //读入valueend_marker = (*stream) ? true : false;}
public:typedef input_iterator_tag iterator_category;   typedef T                  value_type;typedef Distance           difference_type;typedef const T*           pointer;typedef const T&           reference;istream_iterator() : stream(&cin), end_marker(false) {} //默认构造函数,不会触发输入操作istream_iterator(istream& s) : stream(&s) { read(); }   //这种构造函数,后面就紧跟着读取一个数据reference operator*() const { return value; }
#ifndef __SGI_STL_NO_ARROW_OPERATORpointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */istream_iterator& operator++() {          //重点重载operator++read(); return *this;}istream_iterator operator++(int)  {      //将operator++重载为输入操作istream_iterator tmp = *this;read();return tmp;}
};

构造方法:

	istream_iterator intie(cin);                //后面紧跟要输入一个数据istream_iterator intie_();                  //默认构造方法

通过上面的源码知道,当调用istream_iterator对象的operator++操作时,就会被重载为输入一个对象

ostream_iterator

源码:

template 
class ostream_iterator {
protected:ostream* stream;                                                          const char* string;                                                       //可以包含第二个参数,输出对应的数据后,输出此stream
public:typedef output_iterator_tag iterator_category;                            //迭代器类型typedef void                value_type;typedef void                difference_type;typedef void                pointer;typedef void                reference;ostream_iterator(ostream& s) : stream(&s), string(0) {}                 //缺省一个参数的构造函数,默认string为空ostream_iterator(ostream& s, const char* c) : stream(&s), string(c)  {} //包含string的构造函数ostream_iterator& operator=(const T& value) {                        //重点!!!重载operator=操作,转换为输出此value*stream << value;if (string) *stream << string;return *this;}ostream_iterator& operator*() { return *this; }                       //都返回本身ostream_iterator& operator++() { return *this; } ostream_iterator& operator++(int) { return *this; } 
};

构造方式:

	ostream_iterator outie(cout);                           //string默认为nullostream_iterator outie_(cout, " !! ");                  //同时也构造string

通过源码看出,当ostream_iterator遇到operator=操作是,会被重载为输出操作

具体用法

使用ostream_iterator以及istream_iterator的时候,要确保使用对应的方法,例:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;int main()
{deque id;istream_iterator intie(cin),eos;                     //开始触发一次输入   copy(intie, eos, inserter(id, id.begin()));               //迭代器类型为InputIterator,所以这里调用copy的时候采用*result = *first;版本,会使用重载类型 ,那么就会转换为插入操作      //其中++first会继续调用下一个,然后重载为新的输入ostream_iterator outie(cout, " ");                  //deque的迭代器类型为random_access_iterator,也会是 *result = *first;调用赋值操作  result++操作,返回本身,不影响后面的输出操作copy(id.begin(), id.end(), outie);                       //将=操作,转换为输出操作cout << endl;system("pause");
}

我们这里使用的第一个copy方法,里面采用循环赋值的方式进行操作,如下:

template 
inline OutputIterator __copy(InputIterator first, InputIterator last,      //迭代器类型为input_iteratorOutputIterator result, input_iterator_tag)
{for ( ; first != last; ++result, ++first)                               //直接以迭代器是否相等来进行判断循环是否继续进行,速度慢*result = *first;return result;
}

第二个copy方法,也是采用循环赋值的方式操作(因为deque中迭代器的类型为:random_access_iterator_tag):

template 
inline OutputIterator
__copy_d(RandomAccessIterator first, RandomAccessIterator last,           //双向可执行,以n为执行次数,速度快OutputIterator result, Distance*)
{for (Distance n = last - first; n > 0; --n, ++result, ++first)    *result = *first;return result;
}

所以可以直接调用ostream_iterator的对象,进行文本输出

同时copy函数中的++first操作,也会调用istream_iterator对象的++操作,对文本进行输入,在第一个copy函数中的inserter参数为iterator adpapters,可以将赋值操作转换为插入操作,将输入内容插入到deque中。

参考书籍

《STL源码剖析》侯捷著


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部