文档目录
class ThreadPool {
    // ... 同第一阶段 ...

    template <typename F, typename... Args>
    auto enqueue(F&& f, Args&&... args)
        -> std::future<std::invoke_result_t<F, Args...>>
    {
        using ReturnType = std::invoke_result_t<F, Args...>;

        // 把函数和参数打包成一个 packaged_task
        auto task = std::make_shared<std::packaged_task<ReturnType()>>(
            std::bind(std::forward<F>(f), std::forward<Args>(args)...)
        );

        std::future<ReturnType> result = task->get_future();

        {
            std::lock_guard<std::mutex> lock(mtx_);
            if (stop_) throw std::runtime_error("enqueue on stopped ThreadPool");
            tasks_.push([task]() { (*task)(); });
        }
        cv_.notify_one();

        return result;
    }
};

用法:

auto future = pool.enqueue(compute, 42);
// 在这里可以干其他事情...
int result = future.get();  // 阻塞等待结果

// 如果 compute 抛异常,future.get() 会重新抛出异常