一些高层次的代码一般会正好赶上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.
}
档案可用的信息没有被记录(例如文件名)。此外,您还想区分来自存档类的异常和其他异常。
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