最后来到比较坑的代码中:
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; }
而在VS2012和VS2013的结果均为:
没有直接输出我就没有去输入啦。因为这不是我预期的结果
在gnu中编译
如果分开两条线程去处理I和O,是不存在这上面的问题。如果我们需要在同一条线程中交叉访问同个读写缓存区,就得注意这个BUG。
因此,以上三家注明编译器要修改他们的STL实现。
解决方案当然是采用STLport-5.2.1的惰性读取的方式,放弃智能优先读取缓冲区。
第一次尝试写邮件给侯捷大大,不知道结果怎么样?
VS、GNU STL存在一个Bug,而STLport-5.2.1则是没有的。
原文地址:http://blog.csdn.net/jingzhewangzi/article/details/41500645