How does std::async "store" an arbitrary exception?

asynchronous, c++, c++11, exception, future

Solution

`std::async` could be implemented on top of `std::thread` and `std::packaged_task`.

`std::packaged_task` could be implemented (partly) on top of `std::exception_ptr` and related function (except that thread-exit ready function).

`std::exception_ptr` and related functions cannot be written in C++.

Problem

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?

Original source