Anonymous std::packaged_task

Anonymous std::packaged_task

本文关键字:task packaged Anonymous std      更新时间:2023-10-16

我正在尝试围绕Glib::Dispatcher构建一些包装器,以将任何功能类型分派到Dispatcher中。我想要一些函数分派,可以将函数转移到Glib主循环中:

template<class Function, class ...Args>
std::future<typename std::result_of<Function(Args...)>::type>
dispatch(Function &&f, Args &&...args);

这个函数将从f(args)创建一个打包任务并返回它的未来:

std::packaged_task<typename std::result_of<Function(Args...)>::type()> task(f(args...));
return task.get_future();

我现在需要从这个任务中创建一个std::packaged_task<void()>,将它们放入一个std::队列中,以便连接到Glib::Dispatcher的函数可以执行它们。

我的问题是:我如何从一个std::packaged_task<R()>创建一个std::packaged_task<void()>在两个步骤,这样我可以从第一个任务返回它的未来,并把第二个队列的std::queue<std::packaged_task<void()>>类型?

首先,要让std::packaged_task调用具有给定参数集的特定函数,那么(a)您需要在将其传递给std::packaged_task之前将函数绑定到参数,或者(b)您需要将参数传递给std::packaged_task对象的函数调用操作符。在您的代码中,您将f(args...)传递给std::packaged_task构造函数,该构造函数将调用该函数,然后将结果传递给构造函数,这可能不是您想要的,甚至可能无法编译。

其次,如果你在构造时绑定参数,那么你的std::packaged_task实例是一个可调用的对象,它不接受参数并返回void,因此可以将直接移动到std::packaged_task<void()>中。

把这些放在一起,我们得到:

std::queue<std::packaged_task<void()>> task_queue;
template<class Function, class ...Args>
std::future<typename std::result_of<Function(Args...)>::type>
dispatch(Function &&f, Args &&...args) {
    std::packaged_task<typename std::result_of<Function(Args...)>::type()> task(
        std::bind(f,args...));
    auto res=task.get_future();
    task_queue.push(std::packaged_task<void()>(std::move(task)));
    return res;
}