¿Cuál es la diferencia entre packaged_task y async?

Mientras trabajaba con el modelo roscado de C ++ 11, noté que

std::packaged_task<int(int,int)> task([](int a, int b) { return a + b; });
auto f = task.get_future();
task(2,3);
std::cout << f.get() << '\n';

y

auto f = std::async(std::launch::async, 
    [](int a, int b) { return a + b; }, 2, 3);
std::cout << f.get() << '\n';

Parece hacer exactamente lo mismo. Entiendo que podría haber una gran diferencia si corrierastd::async constd::launch::deferred, pero hay uno en este caso?

¿Cuál es la diferencia entre estos dos enfoques y, lo que es más importante, en qué casos de uso debo usar uno sobre el otro?

Respuestas a la pregunta(3)

Su respuesta a la pregunta