Apparently, throwing and catching std::optional<std::exception>::value()
cannot be handled polymorphically. First if we consider
try
{
throw std::logic_error("blah ..");
}
catch(const std::exception& e)
{
std::cout << "E: " << e.what() << std::endl; // OK, outputs "blah .."
}
We get get the expect output, but if we try
std::optional<std::exception> error = std::logic_error("Booo ..");
try
{
throw error.value();
}
catch(const std::exception& e)
{
std::cout << "E: " << e.what() << std::endl; // NOPE, outputs "std::exception"
}
The exception object got sliced.
I understand that this is because I'm actually throwing optional's template type, which is std::exception
and not std::logic_error
. That is, we basically changed the throw
expression in the first example to
std::exception err = std::logic_error("Blah ..");
throw err;
which gives the same behavior.
So how can I make my std::optional<std::exception>::value()
return a derived exception? Does it have to contain a pointer?