C++ 如何使用std::nested_exception和friends?

C++ 如何使用std::nested_exception和friends?,c++,exception-handling,C++,Exception Handling,我注意到在C++11的中还有一些更有趣的声明。有人能解释一下它们的含义和使用方法吗 我想知道的是: ::std::嵌套_异常 ::std::抛出嵌套的\u ::std::如果嵌套,则重新显示 此外,虽然它们似乎不言自明,但了解它们是如何工作的可能会很好: ::std::exception\u ptr ::std::制造例外情况\u ptr ::std::当前异常 ::std::rethrow_异常 一些高级代码通常只捕获std::exception并打印what()。您希望在不丢失任何信息的情况

我注意到在C++11的
中还有一些更有趣的声明。有人能解释一下它们的含义和使用方法吗

我想知道的是:

  • ::std::嵌套_异常
  • ::std::抛出嵌套的\u
  • ::std::如果嵌套,则重新显示
  • 此外,虽然它们似乎不言自明,但了解它们是如何工作的可能会很好:

  • ::std::exception\u ptr
  • ::std::制造例外情况\u ptr
  • ::std::当前异常
  • ::std::rethrow_异常

  • 一些高级代码通常只捕获
    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
    )<代码>嵌套_异常
    旨在解决此问题:

    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));
        }
    }
    
    记录所有可用信息。我们现在可以在catch站点中检索它:

    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);
        }
    }
    
    void打印异常信息(const std::exception&e)
    {
    
    cerr标准中有一个很好的(最好的?)描述。你可以免费阅读最后一个。像
    print\u exception\u info
    这样的东西会不会看起来更好catch…
    ?我通常会在我想做这件事的时候在我的高级异常中保留填充低级异常的位置。但是我可以看到这种通用机制是如何更好,因为你可以有一个非常通用的处理程序来打开它。我借用了你的很多示例-如果你想删除或导入wiki,请随意编辑该wiki如果有人想在GCC中使用它,请记住@Cubbi:是的,这很令人恼火。我也注意到了,不知道是否有人已经提交了错误报告。