#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>
using namespace std;
//直接从输入流中读取数据到输出流中,不经过中间层
//出了些问题,输入str1,不输出,然后输入str2,输出第一次输入的str1,不清楚为什么第一次输入后不输出任何东西。
int main()
{
ostream_iterator<string> out_iter(cout,"/n");
istream_iterator<string> in_iter(cin);
istream_iterator<string> eof;
while(in_iter!=eof)
*out_iter = *(in_iter++);
return 0;
}
输出:
abc //input1
bcd //input2
abc //output1
cde //input3
bcd //output2
def //input4
cde //output3
^Z //input5
def //output4
请按任意键继续. . .
输入str1,不输出,然后输入str2,输出第一次输入的str1,不清楚为什么第一次输入后不输出任何东西?
原帖地址:http://topic.youkuaiyun.com/u/20110428/14/21df0800-6471-4746-a403-d0224d69f81f.html
在Demon__Hunter的提示下,终于略懂一二,在此拿出来与大家分享。
在解释为什么会出现这样的问题之前,先要弄清楚在此过程中涉及的几个来自<iterator>的关键函数:
1,istream_iterator(istream_type& _Istr)
: _Myistr(&_Istr)
{ // construct with input stream
_Getval();
}
2,void _Getval()
{ // get a _Ty value if possible
if (_Myistr != 0 && !(*_Myistr >> _Myval))
_Myistr = 0;
}
3,_Myt operator++(int)
{ // postincrement
_Myt _Tmp = *this;
++*this;
return (_Tmp);
}
4,_Myt& operator++()
{ // preincrement
#if _HAS_ITERATOR_DEBUGGING
if (_Myistr == 0)
{
_DEBUG_ERROR("istream_iterator is not incrementable");
_SCL_SECURE_OUT_OF_RANGE;
}
#else
_SCL_SECURE_VALIDATE_RANGE(_Myistr != 0);
#endif /* _HAS_ITERATOR_DEBUGGING */
_Getval();
return (*this);
}
5, ostream_iterator(ostream_type& _Ostr,
const _Elem *_Delim = 0)
: _Myostr(&_Ostr), _Mydelim(_Delim)
{ // construct from output stream and delimiter
}
6,ostream_iterator<_Ty, _Elem, _Traits>& operator=(const _Ty& _Val)
{ // insert value into output stream, followed by delimiter
*_Myostr << _Val;
if (_Mydelim != 0)
*_Myostr << _Mydelim;
#if _HAS_ITERATOR_DEBUGGING
if (!*_Myostr)
{
_DEBUG_ERROR("ostream_iterator is not dereferencable");
_SCL_SECURE_OUT_OF_RANGE;
}
#else
_SCL_SECURE_VALIDATE_RANGE(*_Myostr != NULL);
#endif /* _HAS_ITERATOR_DEBUGGING */
return (*this);
}
首先:
ostream_iterator<string> out_iter(cout,"/n");
istream_iterator<string> in_iter(cin);
这两句是调用各自的构造函数,参见函数5与函数1。
再来分析一下函数1,函数1调用了函数2,函数2中的语句 *_Myistr >> _Myval 很明显需要输入一个字符串。从函数名上就可以很明显地看出来,getval()就是要输入一串字符串。这时我们输入了:abc,它被保存在in_iter对象中。
然后:
in_iter++
这条语句执行的是函数3,函数3又调用了函数4。函数4中同样有输入函数:getval()。现在我们输入:bcd。现在问题出来了,abc与bcd分别被保存在哪个对象中呢?现在的this指针指向的又是哪个对象呢?答案是明显的。this指针指向的具有值bcd的对象,在函数4中可以很明显地看出这一点来。那之前输入的abc保存在哪里呢?从函数3可以看出,它仍旧在原先的内存空间中,仍旧可以通过指针_Tmp来访问。暂且这么理解吧,现在我并不能很好解释这两个对象之间的关系,又或许这两个对象可能就是一个对象。
然后:
*(in_iter++)
这个就是简单地取字符串操作。将_Tmp对象中保存的字符串("abc")取出。
最后:
*out_iter = *(in_iter++);
调用函数6,将"abc"输出到屏幕中,并事先定义好的分隔符"/n"。
这整个过程就能很好地解释为什么会出现上面的输入了。
那该如何修正呢?
其实很简单,就是帖子二楼所说的:
{
*out_iter = *in_iter;
++in_iter;
}
这样就能完美地解决该问题了。
这和i++有什么不同呢?因为++运算符被重载了,所以产生了完全不同的效果。这下可以体会运算符重载是多么厉害的一个技术了吧!