如何为流提供更好的异常消息?

时间:2015-09-26 06:14:27

标签: c++ c++11 c++-standard-library

问题

截至目前,对流的异常支持非常糟糕。当Boost.System库被C ++ 11采用时,给人的印象是可能异常会得到改善。所做的所有更改都是将std::exception替换为std::system_error。虽然<system_error>本身对开发人员来说是一个很好的库,但标准委员会和标准库实现者并没有采取任何措施来使用它来改进异常消息。

为了说明它有多可怕,这里简要总结了下面的内容:

  • 发生错误。

  • setstate用于设置badbitfailbit

  • clearsetstate调用。

  • 如果启用了例外,则clear会抛出ios_base::failure

是的,这意味着对于所有错误,抛出相同的无用异常消息。这是在basic_ios级别指定的,因此所有派生类都会遇到此问题。违规报价:

  

[iostate.flags] / 4 效果:如果((state | (rdbuf() ? goodbit : badbit)) & exceptions()) == 0,则返回。否则,功能   抛出类fail的对象basic_ios::failure(27.5.3.1.1),   用实现定义的参数值构造。

这是&#34;实现定义的参数值&#34;的示例。给我们:

ios_base::clear: unspecified iostream_category error

有一个简单的解决方法吗?

Boost.FilesystemBoost.Iostreams都不是<iostream>的替代品。前者是一个可移植地处理文件系统的库(很可能出现在C ++的下一个版本中),而后者与.sources和Sinks有关。该文档指出它无论如何都要将例外委托给ios_base::failureBoost.Filesystem 提供<boost/filesystem/fstream.hpp> path使用const char*代替open() template < class charT, class traits = std::char_traits<charT> > class basic_ifstream : public std::basic_ifstream<charT,traits> { private: // disallow copying basic_ifstream(const basic_ifstream&); const basic_ifstream& operator=(const basic_ifstream&); public: basic_ifstream() {} // use two signatures, rather than one signature with default second // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) explicit basic_ifstream(const path& p) : std::basic_ifstream<charT,traits>(p.BOOST_FILESYSTEM_C_STR, std::ios_base::in) {} basic_ifstream(const path& p, std::ios_base::openmode mode) : std::basic_ifstream<charT,traits>(p.BOOST_FILESYSTEM_C_STR, mode) {} void open(const path& p) { std::basic_ifstream<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, std::ios_base::in); } void open(const path& p, std::ios_base::openmode mode) { std::basic_ifstream<charT,traits>::open(p.BOOST_FILESYSTEM_C_STR, mode); } virtual ~basic_ifstream() {} }; 个参数。它显示了一个如何从标准库类继承的示例:

basic_ios

这是一个巧妙的伎俩,除非我们的违规功能是非虚拟的并且在clear()中一直向上,这是我们必须重新实现的组合爆炸:

iostream inheritance diagram

我怀疑需要进行全部重写,因为简单地替换std::system_error就不够了。流可能由于多种原因而失败,但仅抛出一个类型的异常。尽管background-image: url("img/page1/bg shapes.png"); 为我们提供了更好的表达错误的工具,但如果再次无法区分错误来源,则无济于事。

但是,我不是图书馆作家,也不愿意承担这项任务。除了我列出的选项之外还有其他选择吗?

1 个答案:

答案 0 :(得分:3)

Boost是一个开源项目,所以我看到它有两种选择:

  1. 抱怨。编写错误报告或登录邮件列表并建议增强或两者兼而有之。如果社区认为你有一个好点,有人可能会接受
  2. 做1,然后做点什么。您可能会从社区获得一些支持。你可能不是一个图书馆作家,但也许那些背后的人也不是,直到他们是。
  3. 没有神奇的方法来解决它,有人必须做这项工作。