最終更新日時:
が更新

履歴 編集

class
<ios>

std::ios_base::failure

namespace std {
  // C++03 まで
  class ios_base::failure : public exception {
  public:
    explicit failure(const string& msg);
    virtual ~failure();                         // 備考を参照
    virtual const char* what() const throw();
  };

  // C++11 から
  class ios_base::failure : public system_error {
  public:
    explicit failure(const string& msg, const error_code& ec = io_errc::stream);
    explicit failure(const char* msg, const error_code& ec = io_errc::stream);
  };
}

概要

ios_base::failure は、ストリームライブラリ内の関数で、ストリームバッファ操作の間に検出したエラーを報告するために、例外として送出される全てのオブジェクトの型の基底クラスとして定義されている。
C++11 からは、エラー内容としてメッセージだけではなく、error_code を指定出来るようになった。
これによって、ストリームの操作で発生したエラーをプログラムから判別することが容易になる。
例えば、C++ 標準規格には、ストリームライブラリ内部で発生したエラーの error_codeio_errc::streamiostream_category() で、OS レイヤで発生したエラーの error_codesystem_category() で例外を送出するのが一般的だろうとの記載がある。
しかし、少なくとも現時点では error_code はあまり有効に機能していないようである。

メンバ関数

名前 説明 対応バージョン
(constructor) コンストラクタ
what エラーメッセージの取得 C++03 まで

なお、一見 C++11 で what() が無くなっているように見えるが、system_error::what() を継承しているため、メンバ関数自体は使用可能である。

備考

  • ios_base::failure は、C++11 から基底クラスが変更になっている。
    このため、C++03 まででも使用可能とするためには、基底クラスが system_error であることに依存しないようにする必要がある。
    なお、C++ 標準規格では、ライブラリの各クラスは基底クラスを直接継承しなくても(間接的に継承していれば)良いことになっている。
    このため、C++03 でも exception から直接派生していないかもしれないので、注意。
    (当然 C++11 でも system_error を直接継承していない可能性がある)
  • C++03 まではデストラクタが宣言されていたが、例外指定が誤っていたため(基底クラス exception のデストラクタには throw() が付いているため、派生クラスにも throw() が必要)、C++11 では宣言自体が削除された。

バージョン

言語

  • C++98

処理系

  • Clang: 3.0, 3.1, 3.2, 3.3, 3.4, 3.5.0, 3.6.0, 3.7.0, 3.8.0
  • GCC: 4.3.6, 4.4.7, 4.5.4, 4.6.4, 4.7.3, 4.8.1, 4.8.2, 4.9.0, 4.9.1, 4.9.2, 5.1.0, 5.2.0, 6.0.0
  • GCC, C++11 mode: 5.1.0, 5.2.0, 6.0.0
  • ICC: ??
  • Visual C++: ??

備考

  • GCC は 4.9.x までは C++11 モードでも system_error を継承していないので、注意が必要である。
  • GCC 5.1.0 以降は現時点では _GLIBCXX_USE_CXX11_ABI マクロが 1 の場合(通常のビルドでは 1 がデフォルト)、C++03 モードでも C++11 モードでもライブラリ内から送出された例外を ios_base::failure 型では catch できない。
    exception 型であれば catch することができるが、いずれにせよストリーム系の例外とそれ以外の例外を区別することができなくなってしまう。
    したがって、少なくともこの問題が解決されるまでは、_GLIBCXX_USE_CXX11_ABI マクロを 0 にする他ないだろう。(C++03 モードにおける コンストラクタの事後条件の違いも参照)
    なお、_GLIBCXX_USE_CXX11_ABI マクロを 0 にしてしまうと、4.9.x までと同様、モードにかかわらず system_error を継承しなくなってしまうので、注意すること。
  • Clang では、C++03 モードでも strcmp(what(), msg.c_str()) == 0 にはならない。

参照