[英]C++11 exception design. Idioms and best practices changed?
我想知道,自從C ++ 11以來,添加了線程之間的異常並添加了嵌套異常,一般來說,異常捕獲的習語是否已更改。
現在我們有:
std::rethrow_if_nested
std::rethrow_with_nested
std::rethrow_exception
std::current_exception
嵌套異常應該用於不丟失異常的上下文。
所以現在你可以這樣做:
void open_file(std::string const & file_name) {
try {
std::ifstream file;
file.exceptions(ios::failbit | ios::badbit);
file.open(file_name);
}
catch (...) {
std::rethrow_with_nested(std::logic_error("File " + file_name +
" could not be open"));
}
}
如果我沒錯,你可以得到這樣的回溯:
void print_backtrace(std::exception const & e, int depth = 0) {
std::cerr << std::string(depth, ' ') << e.what() << std::endl;
try {
std::rethrow_if_nested(e);
}
catch (std::exception const & ex) {
print_backtrace(ex, ++depth);
}
}
因此,如果您將print_backtrace
與open_file
一起使用,它應該在輸出中為您提供std::logic_error
+ ios_base::failure
。
我的問題是:
print_backtrace
函數中是否有一種方法可以使用catch (...)
捕獲異常以捕獲絕對所有內容? std::rethrow_exception
,我也不知道什么時候。 我不知道我稱之為成語。 如果用''“正確”'表示類似於std::vector
是如何默認使用的'正確'容器,我認為確實沒有一種特定的“正確”處理錯誤的方法。 這是一種正確的方式,因為它是明確定義的行為。
2.首先,您必須在不限於某些異常的上下文中調用print_backtrace()
,這意味着您必須在catch(...)
塊中調用它:
try {
run();
} catch(...) {
print_backtrace();
}
但是,您沒有傳遞給函數的已知類型的例外。 相反,您必須編寫函數來以不同方式訪問異常; 通過拋出該異常並在內部捕獲它(因為這是您可以將已知類型的變量綁定到任意異常的唯一機制)。
void print_backtrace(int depth = 0) {
try {
throw;
}
// this block shows how to handle exceptions of some known type
// You can have your own types instead of std::exception
catch (const std::exception & e) {
std::cerr << std::string(depth, ' ') << e.what() << std::endl;
try {
std::rethrow_if_nested(e);
}
catch (...) {
print_backtrace(++depth);
}
}
// Not all nesting exceptions will be of a known type, but if they use the
// mixin type std::nested_exception, then we can at least handle them enough to
// get the nested exception:
catch (const std::nested_exception & ne) {
std::cerr << std::string(depth, ' ') << "Unknown nesting exception\n";
try {
ne.rethrow_nested();
}
catch (...) {
print_backtrace(++depth);
}
}
// Exception nesting works through inheritance, which means that if you
// can't inherit from the type, then you can't 'mixin' std::nesting exception.
// If you try something like std::throw_with_nested( int{10} ); Then you'll
// hit this catch block when printing the backtrace.
catch (...) {
std::cerr << std::string(depth, ' ') << "Unknown exception\n";
}
}
3. std::rethrow_exception
與std::exception_ptr
,這是一種可用於傳輸任意異常的類型。 獲得該異常的唯一方法是使用正常的異常處理機制來catch
異常,這意味着您必須能夠拋出該異常。 這就是rethrow_exception
作用。 這可以用於將任意異常從一個線程傳輸到另一個線程(如std::future
所做),或者將任意異常作為成員(如std::nested_exception
),或者將任意異常作為參數傳遞一個函數,它將嘗試打印一些異常描述。
void print_backtrace(std::exception_ptr e) {
try {
std::rethrow_exception(e);
}
catch (const std::exception & e) {
// ...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.