8

考虑以下代码片段:

#include <iostream>
#include <sstream>

int main()
{
    std::stringstream ss;
    ss << "12345";
    unsigned short s;
    ss >> s;
    ss << "foo";

    std::cout << std::boolalpha
              << "\nss.eof()  = " << ss.eof()
              << "\nss.good() = " << ss.good()
              << "\nss.bad()  = " << ss.bad()
              << "\nss.fail() = " << ss.fail()
              << "\nss.str()  = " << ss.str();
}

clang++ trunk 打印以下结果:

ss.eof()  = true
ss.good() = false
ss.bad()  = false
ss.fail() = false
ss.str()  = 12345

在魔杖盒上


g++ trunk 打印以下结果:

ss.eof()  = true
ss.good() = false
ss.bad()  = false
ss.fail() = true
ss.str()  = 12345

在魔杖盒上


如您所见,ss.fail()两个编译器之间的值不同。标准对这种情况下的行为有什么看法std::stringstream?在写入已使用的流时设置failbit/是实现定义的吗?badbit

4

1 回答 1

3

海合会是正确的。std::stringstream继承自std::basic_ostream,并根据operator<<(std::basic_ostream)(从 调用ss << "foo";)的行为,

效果:表现得像格式化的插入器(如 [ostream.formatted.reqmts] 中所述)。

并且来自§30.7.5.2.1/1 通用要求 [ostream.formatted.reqmts]

(强调我的)

每个格式化输出函数通过构造一个类哨兵对象开始执行。如果此对象在转换为 bool 类型的值时返回 true,则该函数将努力生成请求的输出。如果生成失败,则格式化输出函数执行 setstate(ios_base​::​failbit),这可能会引发异常。

§30.7.5.1.3 类 basic_ostream​::​sentry [ostream::sentry]

如果 os.good() 不为零,则准备格式化或未格式化的输出。如果 os.tie() 不是空指针,则调用 os.tie()->flush()。

如果在任何准备工作完成后 os.good() 为 true,则 ok_ == true 否则,ok_ == false。在准备过程中,构造函数可能会调用 setstate(failbit) (可能会抛出 ios_base​::​failure ([iostate.flags]))

§30.5.5.4 basic_ios 标志功能 [iostate.flags]

iostate rdstate() 常量;
返回: 流缓冲区的错误状态。

布尔好()常量;
返回:rdstate() == 0

bool eof() 常量;
返回: 如果在 rdstate() 中设置了 eofbit,则返回 true。

eofbit在这种情况下已经设置,然后std::basic_ios::good返回非零并导致写入失败(如结果所示),那么failbit应该设置。

于 2017-11-22T16:13:39.747 回答