I am not able to understand how is it possible for std::async
to store any exception, not just something derived from std::exception
. I played around with the code below
#include <iostream>
#include <future>
#include <chrono>
void f()
{
std::cout << "\t\tIn f() we throw an exception" << std::endl;
throw 1; // throw an int
}
int main()
{
std::future<void> fut = std::async(std::launch::async, f);
std::cout << "Main thread sleeping 1s..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1)); // sleep one second
std::cout << "Main thread waking up" << std::endl;
try
{
fut.get();
}
catch(...)
{
std::cout << "We caught an exception!" << std::endl;
throw; // rethrow
}
}
I launch f()
asynchronously, then throw an int
inside f
. Magically, this int
is caught and stored by the future returned by std::async
. I understand that is possible to catch(...)
the exception in std::async
, but how can the latter store it without knowing the exception type? The exception is not derived from some base class (in this case one perhaps can "clone" it via some Base::clone
), but can be any exception. Can we somehow magically "deduce" the exception type?
To summarize, my question is:
How can we store an arbitrary exception inside an object then re-throw it at some later time, without knowing the exception type?