【问题标题】:Can cout throw an exception?cout 可以抛出异常吗?
【发布时间】:2018-06-22 01:20:06
【问题描述】:
  • cout 是“ost​​ream”类型的实例
  • ostream::operator<< 这么说

    If the operation sets an internal state flag that was registered with
    member exceptions, the function throws an exception of member type failure.
    

这向我表明 cout 可以抛出异常。这是真的?什么样的情况会迫使这种情况发生?

【问题讨论】:

  • 是的,这是真的,就像任何 iostream 一样。使用cout.exceptions(mask),其中mask 指定要引发异常的错误条件(badbitfailbit)。然后做一些事情来触发流上的一个或多个错误状态,例如错误的输出操作或(更简单地)使用std::cout.setstate(mask)
  • 不,std::cout 不能抛出异常。它是一个对象(嗯,通常是对对象的引用),而不是一个函数。在std::cout 上运行的函数可以抛出异常。流插入器 (operator&lt;&lt;) 是函数。

标签: c++ cout ostream


【解决方案1】:

是的,但几乎没有人调用 cout.exceptions(iostate) 来启用它。

编辑说明:

std::ios_base 是一个为所有流提供基本实用功能的抽象类。 std::ios_base&lt;CharT, Traits&gt; 是其抽象子类,增加了更多实用功能。

std::ios_base::iostate是位掩码类型,由以下位组成,可以是ored:

badbit (used for weird underlying errors)
eofbit (used after you hit EOF)
failbit (the normal error for badly-formatted input)

此外,iostate::goodbit 等价于 iostate()(基本上是 0)。

通常,当您执行 I/O 时,您会检查流的布尔值以查看是否在每次输入操作之后发生错误,例如if (cin &gt;&gt; val) { cout &lt;&lt; val; } ... 对于输出,可以简单地发出一堆并且只在最后检查成功(或者对于 cout,根本不检查)。

但是,有些人更喜欢异常,因此每个单独的流都可以配置为将其中一些返回值转换为异常:

std::ios_base::iostate exceptions() const;
void exceptions(std::ios_base::iostate except);

这在 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

(请注意,在 Unix 系统上,您必须忽略 SIGPIPE 以便程序甚至有机会 来处理此类错误,因为对于许多程序来说,简单地退出是正确的做 - 这通常是允许 head 工作的原因)

【讨论】:

    猜你喜欢
    • 2012-02-09
    • 1970-01-01
    • 2015-02-13
    • 1970-01-01
    • 2013-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多