# std::packaged_task

< cpp‎ | thread

定义于头文件 `<future>` |  |
template< class > class packaged_task; // 不定义 | (1) | (C++11 起)
template< class R, class ...Args > class packaged_task<R(Args...)>; | (2) | (C++11 起)

类模板 `std::packaged_task` 包装任何可调用 (Callable) 目标（函数、 lambda 表达式、 bind 表达式或其他函数对象），使得能异步调用它。其返回值或所抛异常被存储于能通过 std::future 对象访问的共享状态中。

正如 std::function ， `std::packaged_task` 是多态、具分配器的容器：可在堆上或以提供的分配器分配存储的可调用对象。

### 成员函数

(构造函数) | 构造任务对象 (公开成员函数)
(析构函数) | 析构任务对象 (公开成员函数)
operator= | 移动任务对象 (公开成员函数)
valid | 检查任务对象是否拥有合法函数 (公开成员函数)
swap | 交换二个任务对象 (公开成员函数)
##### 获取结果
get_future | 返回与承诺的结果关联的 std::future (公开成员函数)
##### 执行
operator() | 执行函数 (公开成员函数)
make_ready_at_thread_exit | 执行函数，并确保结果仅在一旦当前线程退出时就绪 (公开成员函数)
reset | 重置状态，抛弃任何先前执行的存储结果 (公开成员函数)

### 非成员函数

std::swap(std::packaged_task) (C++11) | 特化 std::swap 算法 (函数模板)

### 辅助类

std::uses_allocator<std::packaged_task> (C++11)(C++17 前) | 特化 std::uses_allocator 类型特征 (类模板特化)

### 推导指引(C++17 起)

### 示例

    #include <iostream>
    #include <cmath>
    #include <thread>
    #include <future>
    #include <functional>

    // 避免对 std::pow 重载集消歧义的独有函数
    int f(int x, int y) { return std::pow(x,y); }

    void task_lambda()
    {
        std::packaged_task<int(int,int)> task([](int a, int b) {
            return std::pow(a, b);
        });
        std::future<int> result = task.get_future();

        task(2, 9);

        std::cout << "task_lambda:\t" << result.get() << '\n';
    }

    void task_bind()
    {
        std::packaged_task<int()> task(std::bind(f, 2, 11));
        std::future<int> result = task.get_future();

        task();

        std::cout << "task_bind:\t" << result.get() << '\n';
    }

    void task_thread()
    {
        std::packaged_task<int(int,int)> task(f);
        std::future<int> result = task.get_future();

        std::thread task_td(std::move(task), 2, 10);
        task_td.join();

        std::cout << "task_thread:\t" << result.get() << '\n';
    }

    int main()
    {
        task_lambda();
        task_bind();
        task_thread();
    }

输出：

    task_lambda: 512
    task_bind:   2048
    task_thread: 1024

### 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
LWG 3117 | C++17 | `packaged_task` 的推导指引缺失 | 已添加

### 参阅

future (C++11) | 等待被异步设置的值 (类模板)