I\'m a student in my first C++ programming class, and I\'m working on a project where we have to create multiple custom exception classes, and then in one of our event handl
I had a similar problem today, but it turned out I didn't need my solution to solve my problem. Honestly, I couldn't think of real use cases (logging?), and I didn't find much use for it in my code.
Anyway, this is an approach with type lists (requires C++11). I think the advantage of this approach is that there's no need to have a common base class for custom exceptions (except for std::exception, maybe?). In other words, it is not intrusive to your exception hierarchy.
There might be some subtle errors that I am not aware of.
#include
#include
/// Helper class to handle multiple specific exception types
/// in cases when inheritance based approach would catch exceptions
/// that are not meant to be caught.
///
/// If the body of exception handling code is the same
/// for several exceptions,
/// these exceptions can be joined into one catch.
///
/// Only message data of the caught exception is provided.
///
/// @tparam T Exception types.
/// @tparam Ts At least one more exception type is required.
template
class MultiCatch;
/// Terminal case that holds the message.
/// ``void`` needs to be given as terminal explicitly.
template <>
class MultiCatch {
protected:
explicit MultiCatch(const char* err_msg) : msg(err_msg) {}
const char* msg;
};
template
class MultiCatch : public MultiCatch {
static_assert(std::is_base_of::value, "Not an exception");
public:
using MultiCatch::MultiCatch;
/// Implicit conversion from the guest exception.
MultiCatch(const T& error) : MultiCatch(error.what()) {} // NOLINT
/// @returns The message of the original exception.
const char* what() const noexcept {
return MultiCatch::msg;
}
};
/// To avoid explicit ``void`` in the type list.
template
using OneOf = MultiCatch;
/// Contrived example.
void foo() {
try {
bar(); // May throw three or more sibling or unrelated exceptions.
} catch (const OneOf& err) {
log() << "External failure: " << err.what();
throw; // Throw the original exception.
}
}