4

我正在尝试围绕 Glib::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();

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

我的问题是:如何分两步从 a 创建,以便我可以从第一个任务返回它的未来并将第二个任务放入类型队列std::packaged_task<R()>中?std::packaged_task<void()>std::queue<std::packaged_task<void()>>

4

1 回答 1

6

首先,要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;
}
于 2013-04-22T16:43:40.017 回答