実際、先ほどの例は、次のようなかなり長い関数を使用した場合の違いを示しています。
//! sleeps for one second and returns 1
auto sleep = [](){
    std::this_thread::sleep_for(std::chrono::seconds(1));
    return 1;
};
パッケージタスク
Aは、packaged_taskそれが自分だ上で起動しません、あなたはそれを起動する必要があります。
std::packaged_task<int()> task(sleep);
auto f = task.get_future();
task(); // invoke the function
// You have to wait until task returns. Since task calls sleep
// you will have to wait at least 1 second.
std::cout << "You can see this after 1 second\n";
// However, f.get() will be available, since task has already finished.
std::cout << f.get() << std::endl;
std::async
一方、std::asyncwith launch::asyncは別のスレッドでタスクを実行しようとします。
auto f = std::async(std::launch::async, sleep);
std::cout << "You can see this immediately!\n";
// However, the value of the future will be available after sleep has finished
// so f.get() can block up to 1 second.
std::cout << f.get() << "This will be shown after a second!\n";
欠点
ただしasync、すべてに使用する前に、返されたフューチャーには特別な共有状態があることに注意してfuture::~futureください。
std::async(do_work1); // ~future blocks
std::async(do_work2); // ~future blocks
/* output: (assuming that do_work* log their progress)
    do_work1() started;
    do_work1() stopped;
    do_work2() started;
    do_work2() stopped;
*/
したがって、本当の非同期が必要なfuture場合は、返されたを維持する必要があります。または、状況が変化しても結果を気にしない場合は、次のようになります。
{
    auto pizza = std::async(get_pizza);
    /* ... */
    if(need_to_go)
        return;          // ~future will block
    else
       eat(pizza.get());
}   
これに関する詳細については、ハーブサッターの記事を参照asyncして~future、問題を説明し、そしてスコット・マイヤーさんstd::futuresからはstd::async特別ではない洞察を説明しています、。また、この動作はご注意くださいC ++ 14とアップに指定されましたが、だけでなく、一般的にC ++ 11に実装されています。
さらなる違い
を使用std::asyncすると、特定のスレッドでタスクを実行できなくstd::packaged_taskなり、他のスレッドに移動できます。
std::packaged_task<int(int,int)> task(...);
auto f = task.get_future();
std::thread myThread(std::move(task),2,3);
std::cout << f.get() << "\n";
また、をpackaged_task呼び出す前にを呼び出す必要がありますf.get()。そうしないと、将来の準備ができなくなるため、プログラムがフリーズします。
std::packaged_task<int(int,int)> task(...);
auto f = task.get_future();
std::cout << f.get() << "\n"; // oops!
task(2,3);
TL; DR
使用std::asyncあなたには、いくつかの物事が行われ、それが完了したら、本当に気にしない、としたい場合はstd::packaged_task、あなたが他のスレッドに移動するか、後でそれらを呼び出すために物事をラップする場合。または、クリスチャンを引用するには:
  結局のところ、a std::packaged_taskは実装するための下位レベルの機能にすぎstd::asyncません(そのためstd::async、などの他の下位レベルのものと一緒に使用した場合よりも多くの機能を実行できますstd::thread)。単に話されたa std::packaged_taskはaにstd::functionリンクされてstd::futureおりstd::async、std::packaged_task(おそらく別のスレッドで)a をラップして呼び出します。