2011-12-06 26 views
24

我注意到在C++ 11中<exception>有几个更有趣的声明。任何人都可以阐明他们的意思以及如何使用它们?:: std :: nested_exception和朋友有什么好的描述吗?

我想了解一下的是:

  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. 
} 

档案可用的信息没有被记录(例如文件名)。此外,您还想区分来自存档类的异常和其他异常。

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(); } catch ...'? – Cubbi

+0

我一直在预订地点,以便在我想要执行此操作时在高层次例外中填充低级别异常。但是我可以看到这个通用机制是如何更好的,因为你可以拥有一个非常通用的处理器来解开它。 – Omnifarious

+0

我借鉴了[cppreference.com]的大部分示例(http://en.cppreference.com/w/cpp/error/exception/nested_exception) - 如果您希望删除或改进该wiki,请随时编辑该wiki。 – Cubbi

相关问题