请考虑以下代码:
#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?铛?
答案 0 :(得分: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.
答案 1 :(得分:2)
根据我的理解,libc ++就在这里,但它并不是唯一正确的行为。
N4140§20.6.4[bitset.operators]
效果:从is中提取最多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
应归零,否则应抛出上述异常。
如果没有抛出异常,您可能想测试您的操作是否成功(通过测试返回的流)。