2011-12-06 24 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

相關問題