If the operation sets an internal state flag that was registered with
member exceptions, the function throws an exception of member type failure.
Run Code Online (Sandbox Code Playgroud)这向我表明 cout 可以抛出异常。这是真的?什么样的场景会迫使这个?
是的,但实际上没有人要求cout.exceptions(iostate)启用它。
编辑阐述:
std::ios_base是一个抽象类,为所有流提供基本的实用功能。std::ios_base<CharT, Traits>是其抽象子类,增加了更多的实用功能。
std::ios_base::iostate是位掩码类型,由以下位组成,可以or编辑:
badbit (used for weird underlying errors)
eofbit (used after you hit EOF)
failbit (the normal error for badly-formatted input)
Run Code Online (Sandbox Code Playgroud)
此外,iostate::goodbit相当于iostate()(基本上是 0)。
通常,当您执行 I/O 时,您会检查流的布尔值以查看是否发生错误,在每次输入操作之后,例如if (cin >> val) { cout << val; }... 对于输出,可以简单地发出一堆并仅在最后检查成功(或对于 cout,根本不检查)。
但是,有些人更喜欢异常,因此可以将每个单独的流配置为将其中一些返回值转换为异常:
std::ios_base::iostate exceptions() const;
void exceptions(std::ios_base::iostate except);
Run Code Online (Sandbox Code Playgroud)
这在 C++ 中很少做,因为我们不会像其他一些语言的拥护者那样盲目崇拜异常。特别是,“I/O 出现问题”是一种常见情况,因此扭曲控制流是没有意义的。
一个例子:
$ cat cout.cpp
#include <iostream>
int main()
{
std::cout.exceptions(std::cout.badbit);
std::cout << "error if written to a pipe" << std::endl;
}
$ sh -c 'trap "" PIPE; ./cout | true'
vvv 2018-06-21 23:33:13-0700
terminate called after throwing an instance of 'std::ios_base::failure[abi:cxx11]'
what(): basic_ios::clear: iostream error
Aborted
Run Code Online (Sandbox Code Playgroud)
(请注意,在 Unix 系统上,您必须忽略 SIGPIPE 以便程序甚至有机会处理此类错误,因为对于许多程序而言,简单地退出是正确的做法 - 这通常是允许head工作的)