推荐答案
// www.javascriptcn.com code example
#include <iostream>
#include <future>
#include <thread>
#include <functional>
int main() {
// 创建一个 packaged_task,包装一个 lambda 函数
std::packaged_task<int(int, int)> task([](int a, int b) {
return a + b;
});
// 获取与 packaged_task 关联的 future
std::future<int> result = task.get_future();
// 在一个新线程中执行任务
std::thread t(std::move(task), 2, 3);
// 等待任务完成并获取结果
std::cout << "Result: " << result.get() << std::endl;
// 等待线程结束
t.join();
return 0;
}本题详细解读
1. std::packaged_task 是什么?
std::packaged_task 是 C++11 引入的一个类模板,用于包装一个可调用对象(如函数、lambda 表达式等),并将其执行结果与一个 std::future 对象关联。通过 std::packaged_task,你可以将任务的执行与结果的获取分离开来。
2. std::packaged_task 的使用步骤
创建
std::packaged_task对象:你需要指定任务的签名(即函数的参数类型和返回类型),并将可调用对象传递给std::packaged_task的构造函数。获取
std::future对象:通过调用get_future()方法,你可以获得一个与std::packaged_task关联的std::future对象。这个std::future对象可以用来获取任务的执行结果。执行任务:你可以通过调用
std::packaged_task对象的operator()来执行任务,或者将其传递给一个线程(如std::thread)来异步执行。获取结果:通过
std::future对象的get()方法,你可以获取任务的执行结果。如果任务尚未完成,get()会阻塞当前线程,直到任务完成。
3. 代码解析
创建
std::packaged_task:在示例中,我们创建了一个std::packaged_task<int(int, int)>对象,它包装了一个 lambda 函数,该函数接受两个整数并返回它们的和。获取
std::future:通过task.get_future()获取与std::packaged_task关联的std::future对象。执行任务:我们将
std::packaged_task对象移动到std::thread中,并在新线程中执行任务。获取结果:在主线程中,我们通过
result.get()获取任务的执行结果,并输出到控制台。
4. 注意事项
std::packaged_task对象是不可复制的,但可以通过std::move进行移动。std::future的get()方法只能调用一次,调用后std::future对象将变为无效状态。- 如果任务抛出异常,
std::future的get()方法会重新抛出该异常。