I have a library, and I wish to leverage the design of boost::system::system_error. C++ adopted this design in 2011 with std::system_error. I would like for client code to have the option of working with Boost exceptions or with Standard exceptions. Therefore, when my library code needs to communicate an error, I throw my own exception type that inherits from boost::system::system_error
and std::system_error
:
class my_exception : public std::system_error, public boost::system::system_error {
// implementation
};
Unfortunately, this is a Deadly Diamond of Death with respect to the common base class std::runtime_error
. Nonetheless, client code is able to catch these exceptions as either std::system_error
or as 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
}
However, an expression of type my_exception
cannot bind to a reference to std::runtime_error
(or it's base class, std::exception
), due to the ambiguity of the diamond: should it bind to std::system_error
's base class object, or should it bind to boost::system::system_error
's base class object? The result is that the thrown object is not caught at all:
try {
} catch (const std::runtime_error& ex) {
// Doesn't catch here!
} catch (...) {
std::printf("Sadness\n");
}
The main question: Is there a way to communicate to the compiler which base class subobject shoud be preferred when binding a deadly-diamond-type to a reference-to-base? In normal code you could static_cast<const std::runtime_error&>(ex)
or static_cast<const boost::system::system_error&>(ex)
, but I can't write a static_cast
into the compiler's magical exception-handling code.
Secondary question: Is there a better way make my code interoperable with both std::
and boost::system::
error handling?
Aucun commentaire:
Enregistrer un commentaire