2016-11-23 39 views
4

考慮下面的代碼:差異的行爲愨的libstdC++和的libC++:操作>>對位集

#include <bitset> 
#include <sstream> 
#include <iostream> 

int main(int argc, char* argv[]) 
{ 
    std::stringstream stream; 
    std::bitset<1> bitset(1); 
    std::cout<<"before = "<<bitset[0]<<std::endl; 
    stream<<"4"; 
    stream>>bitset; 
    std::cout<<"after = "<<bitset[0]<<std::endl; 
    return 0; 
} 

g++下編譯時libstdc++,結果是:

> g++ bitset_empty.cpp -o bitset_empty 
> ./bitset_empty 
before = 1 
after = 1 

clang++下編譯時libc++ ,結果是:

> clang++ -stdlib=libc++ bitset_empty.cpp -o bitset_empty 
> ./bitset_empty 
before = 1 
after = 0 

哪一個是對的?兩者(因爲未定義的行爲?)? GCC?鐺?

回答

2

從我的理解,libc中++就在這裏,但它不是唯一正確的行爲。

N4140§20.6.4[bitset.operators]

效果:提取最多n個字符由是。將這些字符存儲在basic_string<charT, traits>類型的臨時對象str中,然後評估表達式x = bitset<N>(str)。 提取字符並存儲,直到發生以下任何情況:

  • N個字符已被提取並存儲;
  • 文件結束髮生在輸入序列上;
  • 下一個輸入字符既不是is.widen(’0’)也不是is.widen(’1’)(在這種情況下輸入字符未被提取)。

如果沒有字符被存儲在str,調用 is.setstate(ios_base::failbit)(這可能會引發ios_base::failure (27.5.5.4))

要注意x = bitset<N>(str)是不是條件是很重要的。如果不拋出ios_base::failure,那就是執行的表達式。而bitset<N>(""s)(即空串)爲0

因此,根據我的理解,您的bitset應該歸零或上述異常應該被拋出。

如果沒有拋出異常,您可能需要測試操作是否成功(通過測試返回的流)。

2

您應該檢查

stream>>bitset; 

是否成功。如果沒有,那麼在此之後你不能指望bitset的值。

#include <bitset> 
#include <sstream> 
#include <iostream> 

int main(int argc, char* argv[]) 
{ 
    std::stringstream stream; 
    std::bitset<1> bitset(1); 
    std::cout<<"before = "<<bitset[0]<<std::endl; 
    stream<<"4"; 
    if (stream>>bitset) 
    { 
     std::cout<<"after = "<<bitset[0]<<std::endl; 
    } 
    else 
    { 
     std::cout << "Failed to restore bitset from stream.\n"; 
    } 
    return 0; 
} 

輸出使用G ++ 4.9.3:

before = 1 
Failed to restore bitset from stream.