最后来到比较坑的代码中:
SGI:
istream_iterator(istream_type& _Istr)
: _Myistr(&_Istr)
{ // construct with input stream
_Getval();
}
SGI PORT:
istream_iterator(istream_type& _Istr)
: _Myistr(&_Istr)
{ // construct with input stream
_Getval();
}
istream_iterator(istream_type& _Istr)
: _Myistr(&_Istr)
{ // construct with input stream
_Getval();
}
GCC4.8.3:
istream_iterator(istream_type& _Istr)
: _Myistr(&_Istr)
{ // construct with input stream
_Getval();
}
VS2012:
istream_iterator(istream_type& _Istr)
: _Myistr(&_Istr)
{ // construct with input stream
_Getval();
}
VS2013 :update 1
istream_iterator(istream_type& _Istr)
: _Myistr(&_Istr)
{ // construct with input stream
_Getval();
}
这是多么坑的一个bug。当同时进行一个对象进行io绑定时候,要特别注意切换带来数据差异,比如下面的代码:
std::istream_iterator<int> in_it(cin),eos;//这里有个bug,必须要用多线程解决。程序主线程启动读写,等待输入操作中断置位,vs_stl不提供切换操作。MS的STL中insert_iterator采用主动读取数据的操作,主线程将中断读取操作中。这会导致一个严重的bug,即构建某个IO操作时提前完成了数据操作,而这可能不是我们期望的。
cout<<"less(3,13):"<<std::less<int>()(3,13)<<endl;//先声明(对象即初始化)再调用
while (!(in_it==eos))
{
cout<<*in_it;
cout<<endl;
++in_it;
}
在STL port的环境中运行结果:
而在VS2012和VS2013的结果均为:
没有直接输出我就没有去输入啦。因为这不是我预期的结果
在gnu中编译
如果分开两条线程去处理I和O,是不存在这上面的问题。如果我们需要在同一条线程中交叉访问同个读写缓存区,就得注意这个BUG。
因此,以上三家注明编译器要修改他们的STL实现。
解决方案当然是采用STLport-5.2.1的惰性读取的方式,放弃智能优先读取缓冲区。
第一次尝试写邮件给侯捷大大,不知道结果怎么样?