1

How to create a packaged_task of a function object ?

For example,

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();
        }
};

Now create a function object first:

std::function<int(void)> func1 = xy; // xy is some function
TaskA task1(func1);

Now I have a function that takes this function object as a parameter, creates a packaged_task and returns a future.

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);
}

and later use this handle function as follows:

auto x = handle(task1);

Can you please help me with the proper syntax for the future as well as the packaged_task declaration?

Thanks !

4

2 回答 2

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);
}
于 2019-09-14T08:19:45.310 回答
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;
}

活的例子在这里

于 2019-09-14T08:46:01.573 回答