Мне интересно, с тех пор как С++ 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"));
}
}
Вы можете получить backtrace, как это, если я не ошибаюсь:
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
+ the ios_base::failure
на выходе.
Мои вопросы:
- Является ли эта идиома "правильным" способом обработки исключений в С++ 11, учитывая, что я хочу фиксировать все исключения без потери контекста?
- Есть ли способ в
print_backtrace
для захвата исключений с помощьюcatch (...)
для полного захвата? - Я не знаю, почему требуется
std::rethrow_exception
, и я не знаю, когда.