bam*_*s53 12 c++ exception raii nested-exceptions c++11
所以在C++中嵌套异常的方法std::nested_exception是:
void foo() {
try {
// code that might throw
std::ifstream file("nonexistent.file");
file.exceptions(std::ios_base::failbit);
}
catch(...) {
std::throw_with_nested(std::runtime_error("foo failed"));
}
}
Run Code Online (Sandbox Code Playgroud)
但是这种技术在每个级别使用显式的try/catch块,希望嵌套异常,这至少可以说是丑陋的.
Jon Kalb扩展为"责任获取是初始化"的RAII,是处理异常而不是使用显式try/catch块的更清晰的方法.使用RAII,显式try/catch块主要仅用于最终处理异常,例如,为了向用户显示错误消息.
查看上面的代码,在我看来,输入foo()可以被视为有责任报告任何异常,std::runtime_error("foo failed")并将细节嵌套在嵌套异常中.如果我们可以使用RAII来获得这个责任,那么代码看起来会更清晰:
void foo() {
Throw_with_nested on_error("foo failed");
// code that might throw
std::ifstream file("nonexistent.file");
file.exceptions(std::ios_base::failbit);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法在这里使用RAII语法来替换显式的try/catch块?
为此,我们需要一种类型,当它的析构函数被调用时,检查析构函数调用是否是由异常引起的,如果是,则嵌套该异常,并抛出新的嵌套异常,以便正常地展开.这可能看起来像:
struct Throw_with_nested {
const char *msg;
Throw_with_nested(const char *error_message) : msg(error_message) {}
~Throw_with_nested() {
if (std::uncaught_exception()) {
std::throw_with_nested(std::runtime_error(msg));
}
}
};
Run Code Online (Sandbox Code Playgroud)
但是,std::throw_with_nested()要求"当前处理的异常"处于活动状态,这意味着除了catch块的上下文之外它不起作用.所以我们需要这样的东西:
~Throw_with_nested() {
if (std::uncaught_exception()) {
try {
rethrow_uncaught_exception();
}
catch(...) {
std::throw_with_nested(std::runtime_error(msg));
}
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,就我所知,rethrow_uncaught_excpetion()C++中没有任何定义.
如果没有在析构函数中捕获(和消耗)未捕获的异常的方法,则无论是否嵌套,都无法在析构函数的上下文中重新抛出异常而不被std::terminate调用(当在上下文中抛出异常时)异常处理)。
std::current_exception(与 结合std::rethrow_exception)只会返回指向当前处理的异常的指针。这阻止了它在这种情况下的使用,因为这种情况下的异常是明确未处理的。
鉴于上述情况,唯一给出的答案是从美学角度。函数级别的 try 块使这个看起来稍微不那么难看。(根据您的风格偏好进行调整):
void foo() try {
// code that might throw
std::ifstream file("nonexistent.file");
file.exceptions(std::ios_base::failbit);
}
catch(...) {
std::throw_with_nested(std::runtime_error("foo failed"));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
598 次 |
| 最近记录: |