4

考虑以下代码:

#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++在with下编译libstdc++,结果为:

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

clang++在with下编译libc++,结果为:

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

哪一个是对的?两者(因为未定义的行为)?海合会?铛?

4

2 回答 2

3

你应该检查是否

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.
于 2016-11-23T07:19:57.897 回答
3

据我了解,libc++ 就在这里,但它不是唯一正确的行为。

N4140 §20.6.4 [bitset.operators]

效果:从 is 中提取最多 N 个字符。将这些字符存储在类型为 str 的临时对象中basic_string<charT, traits>,然后计算表达式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应该归零,或者应该抛出上述异常。

如果没有抛出异常,您可能需要测试您的操作是否成功(通过测试返回的流)。

于 2016-11-23T07:25:58.150 回答