创建一个 packaged_task 的函数对象

Create a packaged_task of function object

如何创建函数对象的 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 和 returns 一个未来。

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

能否请您帮助我了解 futurepackaged_task 声明的正确语法?

谢谢!

这使用元函数来推导签名。请注意,我没有使用其他类型的可调用对象对此进行测试,因此虽然它应该适用于任何带有 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);
}

我会尽量明确说明 return 任务的类型、函数类型和调用签名,并将其作为 class 接口的一部分。为简单起见,我做了所有明确的,但这可以通过模板或使用 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;
}

live example here