`std::stringstream::fail()` return 在读取和写入之后应该有什么值? (海湾合作委员会与铿锵声)
What value should `std::stringstream::fail()` return after reading then writing? (gcc vs clang)
考虑以下代码片段:
#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
是否是实现定义的?
Gcc 是正确的。 std::stringstream
继承自 std::basic_ostream
,并且根据 operator<<(std::basic_ostream)
的行为(从 ss << "foo";
调用),
Effects: Behaves like a formatted inserter (as described in [ostream.formatted.reqmts]) of out.
来自 §30.7.5.2.1/1 Common requirements [ostream.formatted.reqmts]:
(强调我的)
Each formatted output function begins execution by constructing an object of class sentry. If this object returns true when converted to a value of type bool, the function endeavors to generate the requested output. If the generation fails, then the formatted output function does setstate(ios_base::failbit), which might throw an exception.
和§30.7.5.1.3 Class basic_ostream::sentry [ostream::sentry]:
If os.good() is nonzero, prepares for formatted or unformatted output.
If os.tie() is not a null pointer, calls os.tie()->flush().
If, after any preparation is completed, os.good() is true, ok_ ==
true otherwise, ok_ == false. During preparation, the constructor may
call setstate(failbit) (which may throw ios_base::failure
([iostate.flags]))
和§30.5.5.4 basic_ios flags functions [iostate.flags]:
iostate rdstate() const;
Returns: The error state of the stream buffer.
bool good() const;
Returns: rdstate() == 0
bool eof() const;
Returns: true if eofbit is set in rdstate().
本例设置了eofbit
,则std::basic_ios::good
returns非零,导致写入失败(结果显示),则应设置failbit
。
考虑以下代码片段:
#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
是否是实现定义的?
Gcc 是正确的。 std::stringstream
继承自 std::basic_ostream
,并且根据 operator<<(std::basic_ostream)
的行为(从 ss << "foo";
调用),
Effects: Behaves like a formatted inserter (as described in [ostream.formatted.reqmts]) of out.
来自 §30.7.5.2.1/1 Common requirements [ostream.formatted.reqmts]:
(强调我的)
Each formatted output function begins execution by constructing an object of class sentry. If this object returns true when converted to a value of type bool, the function endeavors to generate the requested output. If the generation fails, then the formatted output function does setstate(ios_base::failbit), which might throw an exception.
和§30.7.5.1.3 Class basic_ostream::sentry [ostream::sentry]:
If os.good() is nonzero, prepares for formatted or unformatted output. If os.tie() is not a null pointer, calls os.tie()->flush().
If, after any preparation is completed, os.good() is true, ok_ == true otherwise, ok_ == false. During preparation, the constructor may call setstate(failbit) (which may throw ios_base::failure ([iostate.flags]))
和§30.5.5.4 basic_ios flags functions [iostate.flags]:
本例设置了iostate rdstate() const;
Returns: The error state of the stream buffer.bool good() const;
Returns: rdstate() == 0bool eof() const;
Returns: true if eofbit is set in rdstate().
eofbit
,则std::basic_ios::good
returns非零,导致写入失败(结果显示),则应设置failbit
。