я пытаюсь построить некоторую оболочку вокруг 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();
Мне нужно создать сейчас из этой задачи std::packaged_task<void()>
поместить их в одну очередь std :: queue, чтобы подключенная к 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;
}
Других решений пока нет …