最後來到比較坑的代碼中:
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 1istream_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的惰性讀取的方式,放棄智能優先讀取緩衝區。
第一次嘗試寫郵件給侯捷大大,不知道結果怎麼樣?