一部の高レベルのコードを総称して、単に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()
を呼び出すと、実装は例外をコピーできます。
標準では良い(?)の説明があります。最後の[公開されているドラフト](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf)を無料で読むことができます。 – ybungalobill