重用C ++中的异常处理代码 [英] Reusing exception handling code in C++
问题描述
我具有这两个功能,具有重复的异常处理,其唯一目的是显示错误消息:
I have these two functions, with duplicated exception treatment, which has the sole purpose of displaying an error message:
void func1() noexcept {
try {
do_task();
do_another_task();
} catch (const std::out_of_range& e) {
show_msg("Out of range error", e.what());
} catch (const std::logic_error& e) {
show_msg("Logic error", e.what());
} catch (const std::system_error& e) {
show_msg("System error", e.what());
} catch (const std::runtime_error& e) {
show_msg("Runtime error", e.what());
} catch (const std::exception& e) {
show_msg("Generic error", e.what());
}
}
void func2() noexcept {
try {
do_something();
do_something_else();
do_even_more();
} catch (const std::out_of_range& e) {
show_msg("Out of range error", e.what());
} catch (const std::logic_error& e) {
show_msg("Logic error", e.what());
} catch (const std::system_error& e) {
show_msg("System error", e.what());
} catch (const std::runtime_error& e) {
show_msg("Runtime error", e.what());
} catch (const std::exception& e) {
show_msg("Generic error", e.what());
}
}
我可以只处理 std :: exception
并显示一条通用消息,但是我想更具体一些,这就是为什么我捕获了所有可能的异常.
I could just handle std::exception
and show a single generic message, but I want to be more specific, that's why I'm catching all possible exceptions.
我想重用此异常处理代码.我想到了:
I want to reuse this exception treatment code. I thought about this:
void run_treated(std::function<void()> func) noexcept {
try {
func();
} catch // ... all the catches go here
}
void func1() noexcept {
run_treated([]()->void {
do_task();
do_another_task();
});
}
void func2() noexcept {
do_something();
do_something_else();
do_even_more();
}
- 这是一个好方法吗?
- 如果是这样,
run_治疗
将被称为很多.我应该关注性能吗? - 还有其他方法吗?
- Is this a good approach?
- If so,
run_treated
will be called a lot. Should I be concerned about performance? - Any other approaches?
推荐答案
There's the option of using a Lippincott Function to centralize the exception handling logic. Consider this:
void Lippincott () noexcept {
try {
throw;
} catch (const std::out_of_range& e) {
show_msg("Out of range error", e.what());
} catch (const std::logic_error& e) {
show_msg("Logic error", e.what());
} catch (const std::system_error& e) {
show_msg("System error", e.what());
} catch (const std::runtime_error& e) {
show_msg("Runtime error", e.what());
} catch (const std::exception& e) {
show_msg("Generic error", e.what());
}
}
void func1() noexcept {
try {
do_task();
do_another_task();
} catch (...) {
Lippincott();
}
}
void func2() noexcept {
try {
do_something();
do_something_else();
do_even_more();
} catch (...) {
Lippincott();
}
}
它如何工作?当您在 func1
或 func2
中输入处理程序时,将处理当前异常".Lippincott 的正文开始一个新的try..catch块,然后将其重新抛出.然后,它捕获适当的异常并集中处理它们.
How does it work? When you enter the handler in func1
or func2
there is a "current exception" being processed. The body of Lippincott
starts a new try..catch block and re-throws it. Then it catches the appropriate exceptions and handles them accordingly in a centralized manner.
您还应该注意,您的异常处理逻辑并非真正地 noexcept
.从理论上讲,您的列表中可能没有某些例外.在这种情况下,根据您如何标记事物 noexcept
You should also note that your exception handling logic isn't really noexcept
. There could theoretically be exceptions not covered by your list. In which case there are several places for std::terminate
to be called, depending on how you mark things noexcept
这篇关于重用C ++中的异常处理代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!