Is there a packaged_task::set_exception equivalent?

c++11, exception, future, packaged-task, promise

Solution

An `std::packaged_task` has an associated `std::future` object that will hold the exception (or the result of the task). You can retrieve that future by calling the `get_future()` member function of `std::packaged_task`.

This means that it is enough to `throw` an exception inside the function associated with the packaged task in order for that exception to be caught by the task's future (and re-thrown when `get()` is called on the future object).

For instance:

#include <thread>
#include <future>
#include <iostream>

int main()
{
    std::packaged_task<void()> pt([] () { 
        std::cout << "Hello, "; 
        throw 42; // <== Just throw an exception...
    });

    // Retrieve the associated future...
    auto f = pt.get_future();

    // Start the task (here, in a separate thread)
    std::thread t(std::move(pt));

    try
    {
        // This will throw the exception originally thrown inside the
        // packaged task's function...
        f.get();
    }
    catch (int e)
    {
        // ...and here we have that exception
        std::cout << e;
    }

    t.join();
}

Problem

My assumption is that `packaged_task` has a `promise` underneath. If my task throws an exception, how do I route that to the associated `future`? With just a `promise` I could call `set_exception ` – how do I do the same for `packaged_task`?

Original source