2011-12-06 9 views
24

私はC++ 11の<exception>にいくつか興味深い宣言があることに気付きました。誰でも彼らが何を意味し、どのようにそれらを使用するかについての光を放つことができますか? :: std :: nested_exceptionとfriendsの説明はありますか?

私が思ったんだけどなもの

は以下のとおりです。

  1. ::std::nested_exception
  2. ::std::throw_with_nested
  3. ::std::rethrow_if_nested

また、彼らは自明に見えるが、どのように知っていることは素晴らしいかもしれませんこれらは働いた:

  1. ::std::exception_ptr
  2. ::std::make_exception_ptr
  3. ::std::current_exception
  4. ::std::rethrow_exception
+1

標準では良い(?)の説明があります。最後の[公開されているドラフト](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf)を無料で読むことができます。 – ybungalobill

答えて

22

一部の高レベルのコードを総称して、単にstd::exceptionをキャッチし、what()を印刷します。できるだけ多くの情報をこの一般的なメカニズムに絞って、情報を失うことはありません。アーカイブライブラリの実装を検討してください。

archive::archive(const char* filename) 
{ 
    ifstream file(filename) 
    file.exceptions(ios_base::badbit); 
    open_archive(file); // throws ios_base::failure, or some other low-level exception. 
} 

アーカイブに利用可能な情報は記録されません(例:filename)。あなたは、アーカイブクラスから来た例外と他の例外とを区別したいと思います。

archive::archive(const char* filename) 
{ 
    try { 
     ifstream file(filename) 
     file.exceptions(ios_base::badbit); 
     open_archive(file); // throws ios_base::failure, or some other low-level exception. 
    } catch(const std::exception& e) { 
     throw archive_exception("Can't open archive", filename, e.what()); 
    } 
} 

は、今、私たちはarchiveクラスが知っていることをより高いレベルの意味情報を追加しましたが、我々はまた、問題の元の原因(eの種類)についての情報を失いました。 nested_exceptionは、この問題を解決するためのものです:

archive::archive(const char* filename) 
{ 
    try { 
     ifstream file(filename) 
     file.exceptions(ios_base::badbit); 
     open_archive(file); // throws ios_base::failure, or some other low-level exception. 
    } catch(...) { 
     throw_with_nested(archive_exception("Can't open archive", filename)); 
    } 
} 

使用可能なすべての情報が記録されています。キャッチサイトで一般的に取得できるようになりました。

void print_exception_info(const std::exception& e) 
{ 
    cerr << e.what() << "\n"; 
    try { 
     rethrow_if_nested(e); 
    } catch(const std::exception& ne) { 
     print_exception_info(ne); 
    } catch(...) { } 
} 

int main() { 
    try { 
     run(); 
    } catch(const std::exception& e) { 
     print_exception_info(e); 
    } 
} 

出力が以前よりも説明的になります。これは、ハイレベルからローレベルに始まるの問題を説明します:

がオープンアーカイブ「my_archive.bin」

アクセスが拒否されたことはできません。

それとも:

がオープンアーカイブ "my_archive.bin"

録音 'AABB' が見つかりませんすることはできません。

exception_ptrで機能する関数は、スレッド間で例外を転送するように設計されています。または、より一般的には、後で使用するために例外を格納します。どのように動作するかは実装によって異なります。意図は、exception_ptrが例外オブジェクトへの共有ポインタになるということでした。しかし、このポインタが作成されたとき、例外をスローするとき、またはexception_ptrを取得しようとするときは、実装の対象となります。 current_exception()を呼び出すと、実装は例外をコピーできます。

+1

'print_exception_info'は' try {std :: rethrow_if_nested();のように良く見えません。 }キャッチ... '? – Cubbi

+0

私はこれをやりたいときに、私の高レベルの例外で低レベルの例外を埋めるために場所を予約していました。しかし、この汎用的な仕組みが、どのように包括的なハンドラを持っているので、この汎用的な仕組みが優れているのか分かります。 – Omnifarious

+0

私は[cppreference.com](http://en.cppreference.com/w/cpp/error/exception/nested_exception)のためにあなたの例の多くを借りていました。削除したり改善したい場合は、そのwikiを自由に編集してください。 – Cubbi

関連する問題