basic_ios 上标志的语义

2021-12-21 00:00:00 input c++ c++-faq

我发现自己一再被 rdstate() 标志弄糊涂了 - good()bad()eof()fail() - 以及它们在 basic_ios::operator!operator booloperator void 中的表达方式*.

I find myself repeatedly baffled by the rdstate() flags - good(), bad(), eof(), fail() - and how they are expressed in basic_ios::operator!, operator bool and operator void*.

有人可以让我摆脱痛苦并解释这一点,这样我就不必再三思了吗?

Could somebody put me out of my misery and explain this so I never have to think twice again?

推荐答案

有三个标志指示错误状态:

There are three flags that indicate error state:

  • badbit 表示流出现了严重问题.这可能是缓冲区错误或向流中提供数据的任何错误.如果设置了此标志,您很可能不会再使用该流.

  • badbit means something has gone very wrong with the stream. It might be a buffer error or an error in whatever is feeding data to the stream. If this flag is set, it's likely that you aren't going to be using the stream anymore.

failbit 意味着从流中提取或读取失败(或写入或插入输出流),您需要注意该失败.

failbit means that an extraction or a read from the stream failed (or a write or insertion for output streams) and you need to be aware of that failure.

eofbit 表示输入流已经结束,没有什么可读取的了.请注意,这仅在您尝试从已到达其末尾的输入流中读取后设置(即,在发生错误时设置,因为您尝试读取不存在的数据).

eofbit means the input stream has reached its end and there is nothing left to read. Note that this is set only after you attempt to read from an input stream that has reached its end (that is, it is set when an error occurs because you try to read data that isn't there).

failbit 也可以由许多到达 EOF 的操作设置.例如,如果流中只剩下空白,并且您尝试读取 int,那么您将同时到达 EOF 并且无法读取 int,因此两个标志都将被设置.

The failbit may also be set by many operations that reach EOF. For example, if there is only whitespace left remaining in the stream and you try to read an int, you will both reach EOF and you will fail to read the int, so both flags will be set.

fail() 函数测试 badbit ||失败位.

good() 函数测试 !(badbit || failbit || eofbit).也就是说,当没有设置任何位时,流是好的.

The good() function tests !(badbit || failbit || eofbit). That is, a stream is good when none of the bits are set.

您可以使用 ios::clear() 成员函数重置标志;这允许您设置任何错误标志;默认情况下(不带参数),它会清除所有三个标志.

You can reset the flags by using the ios::clear() member function; this allows you to set any of the error flags; by default (with no argument), it clears all three flags.

流不会重载operator bool()operator void*() 用于实现安全布尔习语的一个有点损坏的版本.如果设置了 badbitfailbit,则此运算符重载返回 null,否则返回非 null.您可以使用它来支持测试提取成功作为循环或其他控制流语句的条件的习惯用法:

Streams do not overload operator bool(); operator void*() is used to implement a somewhat broken version of the safe bool idiom. This operator overload returns null if badbit or failbit is set, and non-null otherwise. You can use this to support the idiom of testing the success of an extraction as the condition of a loop or other control flow statement:

if (std::cin >> x) {
    // extraction succeeded
}
else {
    // extraction failed
}

operator!() 重载与 operator void*() 相反;如果设置了 badbitfailbit,则返回 true,否则返回 false.operator!() 重载不再需要了;它可以追溯到完全一致地支持运算符重载之前(参见 sbi 的问题 "为什么 std::basic_ios 重载了一元逻辑否定运算符?").

The operator!() overload is the opposite of the operator void*(); it returns true if the badbit or failbit is set and false otherwise. The operator!() overload is not really needed anymore; it dates back to before operator overloads were supported completely and consistently (see sbi's question "Why does std::basic_ios overload the unary logical negation operator?").

C++0x 修复了导致我们必须使用安全 bool 习惯用法的问题,因此在 C++0x 中,basic_ios 基类模板确实重载了 operator bool() 作为显式转换运算符;此运算符与当前的 operator void*() 具有相同的语义.

C++0x fixes the problem that causes us to have to use the safe bool idiom, so in C++0x the basic_ios base class template does overload operator bool() as an explicit conversion operator; this operator has the same semantics as the current operator void*().

相关文章