iostream 算子重载的 C++ 异常规范

C++ exception specification for iostream operator overloading

提问人:Baptistou 提问时间:11/7/2019 更新时间:8/29/2021 访问量:773

问:

未指定对 ostream 运算符的调用<< 可能会失败或抛出任何异常,我从未遇到过这种情况。

  1. 有没有 ostream 运算符<<可能会失败的情况?
  2. 如果不是,为什么标准不把 noexcept 说明符放在这些重载中?
  3. 以下重载是否有效?好的做法 ?常用?
  4. 同样的问题 istream 运营商>>
struct MyClass {
    int data;
    // I/O operators with noexcept specifier
    friend std::istream& operator>>(std::istream &in, MyClass &obj) noexcept;
    friend std::ostream& operator<<(std::ostream &out, const MyClass &obj) noexcept;
};
C++ 运算符重载 IOSTREAM noexcept

评论


答:

8赞 NathanOliver 11/7/2019 #1

没有 和 被标记为的原因是 std::basic_ios::异常。此成员函数存在于继承自的所有对象中,并允许您将流配置为为某些故障模式引发异常。如果运算符是,则不能将它们用于设置了异常的流。operator >>operator <<noexceptstd::basic_iosnoexcept

评论

0赞 11/8/2019
这感觉它只充分回答了第二个问题。话又说回来,OP 不应该在同一个问题中提出很多问题,所以就是这样。
0赞 NathanOliver 11/8/2019
@Chipster 对我来说,如果运算符是 noexcept 那么你就不能将它们与设置了涵盖所有问题的异常集的流一起使用。UB是不做某事的好理由。
0赞 11/8/2019
它没有回答问题 1,我不认为。OP似乎想要一个例子。但我想那只是我。
0赞 NathanOliver 11/8/2019
@Chipster 我真的需要显示一个获得异常集的流,以显示当它遇到错误时如何引发异常吗?
0赞 11/8/2019
我想不是。不过会很好。不过,你说得有道理,所以我还是要投赞成票。
1赞 Arthur P. Golubev 8/25/2021 #2
  1. 它可能会失败,您可以使用返回值来了解结果,也可以使用 std::ostream::exceptions 方法启用异常。

该示例适用于 std::iostream。

#include <iostream>

int main () {

    std::cout.exceptions ( std::ios::failbit | std::ios::badbit );

    try {

        // operations with the stream ...
    
    } catch (const std::ios::failure & ex) {

    }
 
}
  1. 他们通常可以。

  2. 它是有效的,但你必须保证实际上不会抛出异常。如果试图从您提供的方法中抛出异常,则将调用 std::terminate,因为当异常离开它们时,使用 noexcept 声明的函数会发生这种情况。

  3. std::istream 也是如此。