Проблема
Как сейчас, поддержка исключений для потоков ужасна. Когда библиотека Boost.System была принята в С++ 11, у одного создалось впечатление, что, возможно, исключения будут улучшаться. Все изменения были заменены std::exception на std::system_error. Хотя <system_error> является хорошей библиотекой для разработчиков, стандартный комитет и разработчики стандартных библиотек не предприняли никаких шагов по его использованию для улучшения сообщений об исключениях.
Чтобы дать представление о том, как это ужасно, здесь краткое изложение того, что происходит:
-  Произошла ошибка. 
-  setstateиспользуется для установкиbadbitилиfailbit.
-  clearвызываетсяsetstate.
-  Если исключения включены, clearвыдастios_base::failure.
Да, это означает, что для ВСЕХ ошибок генерируется одно и то же ненужное сообщение об исключении. Это указано на уровне basic_ios, поэтому все производные классы страдают от этой проблемы. Оскорбительная цитата:
[iostate.flags]/4 Эффекты: Если
((state | (rdbuf() ? goodbit : badbit)) & exceptions()) == 0, возвращается. В противном случае функция бросает объектfailклассаbasic_ios::failure(27.5.3.1.1), построенные с определенными параметрами аргументов.
Здесь приведен пример того, что "значения аргументов, определяемых реализацией":
ios_base::clear: unspecified iostream_category error
Есть ли легкое исправление?
Ни Boost.Filesystem, ни Boost.Iostreams не являются заменой для <iostream>. Первая представляет собой библиотеку для портативного управления файловой системой (и, вероятно, появится в следующей версии С++), в то время как последняя имеет какое-то отношение к... Источники и стоки. В документации указано, что она делегирует исключения в ios_base::failure в любом случае. Boost.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() будет недостаточно. Поток может завершиться неудачей по нескольким причинам, но есть только один тип исключения. Хотя std::system_error дает нам лучшие инструменты выражения ошибок, это не помогает, если, опять же, нет способа отличить источник ошибки.
Однако я не писатель библиотеки и не хочу заниматься этой задачей. Есть ли другие варианты, кроме перечисленных мной?

