提问人:SumDood 提问时间:10/24/2023 最后编辑:SumDood 更新时间:10/27/2023 访问量:99
捕获 Diamond Of Death 异常(boost::system::system_error 和 std::system_error)
Catching a Diamond Of Death Exception (boost::system::system_error and std::system_error)
问:
我有一个库,我希望利用 boost::system::system_error 的设计。C++ 在 2011 年通过 std::system_error 采用了这种设计。我希望客户端代码可以选择使用 Boost 异常或标准异常。因此,当我的库代码需要传达错误时,我会抛出我自己的异常类型,该异常类型继承自 和 :boost::system::system_error
std::system_error
class my_exception : public std::system_error, public boost::system::system_error {
// implementation
};
不幸的是,这是一颗致命的死亡钻石,相对于共同的基类。尽管如此,客户端代码还是能够将这些异常捕获为以下 or :std::runtime_error
std::system_error
boost::system::system_error
try {
a_function_that_might_throw_my_exception();
} catch (const std::system_error& ex) {
// Works as intended - correctly catches a reference to the `my_exception` object
}
try {
a_function_that_might_throw_my_exception();
} catch (const boost::system::system_error& ex) {
// Also works
}
但是,由于菱形的模糊性,类型的表达式不能绑定到对(或其基类)的引用:它应该绑定到的基类对象,还是应该绑定到的基类对象?结果是抛出的物体根本没有被捕获:my_exception
std::runtime_error
std::exception
std::system_error
boost::system::system_error
try {
a_function_that_might_throw_my_exception();
} catch (const std::runtime_error& ex) {
// Doesn't catch here!
} catch (...) {
std::printf("Sadness\n");
}
主要问题:有没有办法与编译器沟通,在将致命的菱形类型绑定到基的引用时,应该首选哪个基类子对象?在普通代码中,你可以 或 ,但我不能将 a 写入编译器神奇的异常处理代码中。static_cast<const std::runtime_error&>(ex)
static_cast<const boost::system::system_error&>(ex)
static_cast
次要问题:有没有更好的方法可以使我的代码与两者和错误处理互操作?std::
boost::system::
编辑:
问题在于,一些库代码在后台同时使用 API 和 API;因此,我不一定总是可以选择抛出我的选择或。boost::
std::
boost::system::system_error
std::system_error
答: 暂无答案
评论
using exception_base = EXCEPTION_BASE_TO_USE
#ifndef USE_BOOST_EXCEPTIONS #then #define EXCEPTION_BASE_TO_USE std::exception #else #define EXCEPTION_BASE_TO_USE boost::exception
boost::system_error
std::system_error
boost::system_error
error_code
system_error
virtual