2016-11-23 5 views
4

に、オペレータは>>以下のコードを検討:libstdc++g++でコンパイルのlibstdc betwen挙動の違い++との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; 
} 

を、結果は:

libc++clang++でコンパイル
> g++ bitset_empty.cpp -o bitset_empty 
> ./bitset_empty 
before = 1 
after = 1 

結果は次のとおりです。

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

どちらが正しいですか?両方(未定義の動作のため?)? GCC?クラング?

答えて

2

はここですが、それだけで正しい動作ではありません。

N4140§20.6.4[bitset.operators]

効果:抽出物であるからN文字まで。これらの文字をbasic_string<charT, traits>の一時オブジェクトstrに格納し、式x = bitset<N>(str)を評価します。 文字が抽出され、次のいずれかが発生するまで格納されます。

  • N文字が抽出されて保存されています。
  • end-of-fileは入力シーケンスで発生します。
  • 次の入力文字はis.widen(’0’)でもis.widen(’1’)でもありません(この場合、入力文字は抽出されません)。

何の文字がstrに格納されていない場合は、(ios_base::failure (27.5.5.4)をスローする場合があります) is.setstate(ios_base::failbit)

は、それはx = bitset<N>(str)は条件付きではないことに注意することが重要です呼び出します。 ios_base::failureがスローされない場合、それは実行される式です。 bitset<N>(""s)(空の文字列)は0です。

このように、私の理解では、bitsetはゼロにするか、前述の例外がスローされているはずです。

例外がスローされない場合は、操作が成功したかどうかをテストすることができます(返されたストリームをテストして)。

2

あなたは

stream>>bitset; 

が成功したかどうかを確認する必要があります。そうでなければ、それ以降はbitsetの値にはカウントできません。 G ++ 4.9.3使用

#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; 
} 

出力:libcの++、私の理解から、

before = 1 
Failed to restore bitset from stream. 
関連する問題