我们应该如何向一个需要结果的任务引入 future?又如何向一个生成结果的线程引入对应的 promise呢?标准库提供了 packaged_task类型简化任务连接 futurepromise的设置。 packaged_task提供了一层包装代码,负责把某个任务的返回值或异常放入一个 promise中(就像5.3.5.1节中代码所做的那样)。如果通过调用 get_future(来向一个packaged_task发出请求,它会返回给你对应 promisefuture。例如,我们可以将两个任务连接起来,它们各自使用标准库 accumulate()(见3.4.2节和40.6节)算法将一个vector<double>中的一半元素累加起来:

    1. double accum(double* beg,double* end,double init) //计算[beg:end)中元素的和,计算的初始值是init
    2. {
    3. return accumulate(beg,end,init);
    4. }
    5. double comp2(vector<double>& v)
    6. {
    7. using Task_type=double(double*,duble*,double); //任务的类型
    8. packaged_task<Task_type> pt0{accum}; //打包任务(即accum)
    9. packaged_task<Task_type> pt1{accum};
    10. future<double> f0{pt0.get_future()}; //获取pt0的future
    11. future<double> f1{pt1.get_future()}; //获取pt1的future
    12. double* first=&v[0];
    13. thread t1{move(pt0),first,first+v.size()/2,0}; //为pt0启动一个线程
    14. thread t2{move(pt1),first+v.size()/2,first+v.size(),0}; //为pt1启动一个线程
    15. //...
    16. return f0.get()+f1.get(); //获得结果
    17. }

    packaged_task模板接受模板参数表示任务的类型(本例中为 Task_type,即 double(``double* double*, double``)的别名),并接受构造函数参数作为任务(本例中为 accum)。因为 packaged_task不能被拷贝,所以move()操作是必需的。
    请注意这段代码没有显式地使用锁:通过使用 packaged_task,我们可以集中精力于要完成的任务,而不必操心该如何管理它们之间的通信。两个任务运行于两个独立的线程,因此可以并行执行.