`std :: stringstream :: fail()`读取后再写什么值?(gcc vs clang)

Vit*_*meo 8 c++ iostream sstream language-lawyer

请考虑以下代码段:

#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();
}
Run Code Online (Sandbox Code Playgroud)

clang ++ trunk打印出以下结果:

ss.eof()  = true
ss.good() = false
ss.bad()  = false
ss.fail() = false
ss.str()  = 12345
Run Code Online (Sandbox Code Playgroud)

在wandbox上


g ++ trunk打印以下结果:

ss.eof()  = true
ss.good() = false
ss.bad()  = false
ss.fail() = true
ss.str()  = 12345
Run Code Online (Sandbox Code Playgroud)

在wandbox上


如您所见,ss.fail()两个编译器之间的值不同.标准对于std::stringstream这种情况下的行为有何评价?是否实现定义设置failbit/ badbit何时写入已经消耗的流?

son*_*yao 4

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

\n\n
\n

效果:行为类似于 out 的格式化插入器(如 [ostream.formatted.reqmts] 中所述)。

\n
\n\n

并来自\xc2\xa730.7.5.2.1/1 常见要求 [ostream.formatted.reqmts]

\n\n

(强调我的)

\n\n
\n

每个格式化输出函数都通过构造哨兵类的对象来开始执行。如果该对象在转换为 bool 类型的值时返回 true,则该函数将尽力生成请求的输出。如果生成失败,则格式化输出函数会 setstate(ios_\xc2\xadbase\xe2\x80\x8b::\xe2\x80\x8bfailbit),这可能会引发异常。

\n
\n\n

\xc2\xa730.7.5.1.3 类 basic_\xc2\xadostream\xe2\x80\x8b::\xe2\x80\x8bsentry [ostream::sentry]

\n\n
\n

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

\n\n

任何准备工作完成后,如果 os.good() 为 true,则 ok_\xc2\xad ==\n true,否则,ok_\xc2\xad == false。在准备期间,构造函数可能会调用 setstate(failbit) (这可能会抛出 ios_\xc2\xadbase\xe2\x80\x8b::\xe2\x80\x8b\xe2\x80\x8bfailure\n ([iostate.flags] ))

\n
\n\n

\xc2\xa730.5.5.4 basic_\xc2\xadios 标志函数 [iostate.flags]

\n\n
\n

iostate rdstate() const;
\n 返回: 流缓冲区的错误状态。

\n\n

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

\n\n

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

\n
\n\n

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

\n