如何创建功能对象的packaged_task
?
例如,
class TaskA {
public:
std::function<int(void)> func;
TaskA(std::function<int(void)>&f) : func(f) {}
int res;
int operator()() {
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
return func();
}
};
现在首先创建一个函数对象:
std::function<int(void)> func1 = xy; // xy is some function
TaskA task1(func1);
现在我有一个函数,该函数将该函数对象作为参数,创建一个packaged_task
并返回未来。
template<typename TaskType>
auto handle(TaskType func) -> std::future</*correct syntax ?*/>
{
auto task = std::packaged_task</*correct syntax ?*/>(std::move(func));
/* correct syntax ? */
auto futur = task.get_future();
// do something with the task
return std::move(futur);
}
,然后按如下所示使用此句柄函数:
auto x = handle(task1);
您能为我提供future
和packaged_task
声明的正确语法吗?
谢谢!
答案 0 :(得分:1)
这使用一个元函数来推断签名。请注意,我并未在其他类型的可调用对象上进行此测试,因此尽管它可以与operator()
一起使用,但对于其他类型的可调用对象可能还需要一些工作。
#include <functional>
#include <future>
class TaskA {
public:
int operator()() { return 0; }
};
template <typename T>
struct function_signature
: public function_signature<decltype(&T::operator())>
{};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_signature<ReturnType(ClassType::*)(Args...)> {
using type = ReturnType(Args...);
};
template<typename TaskType>
auto handle(TaskType func)
{
using signature = typename function_signature<TaskType>::type;
auto task = std::packaged_task<signature>(std::move(func));
auto futur = task.get_future();
// do something with the task
return std::move(futur);
}
int main() {
TaskA task1;
handle(task1);
}
答案 1 :(得分:1)
我会尝试明确说明任务的返回类型,函数类型和调用签名,并将其作为类接口的一部分。为了简单起见,我做了所有显式操作,但这可以通过模板或使用decltype功能来完成:
#include <cmath>
#include <iostream>
#include <map>
#include <functional>
#include <future>
#include <cmath>
#include <thread>
//#include <gsl/gsl>
using namespace std;
int f()
{
return 3;
}
class TaskA
{
public:
using ReturnType = int;
using Function = std::function<ReturnType(void)>;
typedef ReturnType (CallSignature)();
TaskA(Function& f) : func{f} {}
ReturnType operator()()
{
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
return func();
}
private:
Function func;
};
template<typename TaskType>
auto handle(TaskType func) -> std::future<typename TaskType::ReturnType>
{
auto task = std::packaged_task<typename TaskType::CallSignature>{func};
auto future = task.get_future();
// do something with task
task();
return future;
}
int main()
{
std::function<int()> ff{f};
TaskA task{ff};
auto result = handle(task);
cout << result.get() << endl;
}