I have a custom implementation of std::expected
, but with a type-erased error. It makes the expected type looks similar to exceptions. We just can use the next code:
Expected<int> V = 123;
V.SetError(std::string("Error occurred"));
And when we try to get the value from Expected
, we can just output the stored value to screen (if it supports some function overloading for std::string
or another type that is stored in Expected
).
I think this is good practice if we don't want to use exceptions.
But, it would also be nice to handle the error by its parent class, similar to a try
/catch
:
struct MathError{};
struct ZeroDivisionError : MathError{};
Expected V = 321;
V.SetError(ZeroDivisionError{});
if (auto Error = V.Catch<MathError>())
{
// we go here if error is subclass of MathError
}
But, I have disabled RTTI in my project, and now I can't use dynamic_cast
to upcast the stored error (as void*
) to MathError*
.
Ok, I can make an individual type identifier for each type that is used as an error using a static template function (1 instantiated type = 1 type id).
But, in this case, I can only cast to the exact type if their ids are the same. Maybe something like std::bases
would help me (I could enumerate all the classes and make a list of their ids), but this feature is not available in the standard.
So, is there any chance?