Yonghui
Yonghui

Reputation: 222

How to write .then using std::future

I have a simple task class:

template<typename TType>
class YHMTask
{
public:
    YHMTask() {};
    template<typename TLambdaFun>
    auto then(TLambdaFun f) -> std::future<decltype(f(mTask.get()))>
    {
        std::move(mTask);
        return std::async(std::launch::async, f, mTask.get());
    }
    std::future<TType> mTask;
private:
};

In this code, .then can be used and return a std::future.

But I want .then to return another YHMTask so that I can call .then after .then. I tried to change .then code to follow:

template<typename TLambdaFun>
auto then(TLambdaFun f) -> YHMTask<decltype(f())>
{
    std::move(mTask);
    std::async(std::launch::async, f, mTask.get());
    YHMTask<decltype(f())> yhmTask(std::move(this));
    return yhmTask;
}

And call .then like this:

auto testTask = YHMCreateTask(PostAsync(L"", L"")).then([=](wstring str)
{
    return 1;
});

Compilier give me this error:

error C2672: 'YHMTask<std::wstring>::then': no matching overloaded function found
error C2893: Failed to specialize function template 'YHMTask<unknown-type> YHMTask<std::wstring>::then(TLambdaFun)'

How should I do?

Upvotes: 1

Views: 265

Answers (2)

Atif
Atif

Reputation: 1547

Sounds like you are interested in extending std::future to have .then(). I recommend taking a look at Futures for C++ at Facebook. It does what your attempting to do and more.

Lets you chain a sequence tasks using then:

Future<double> fut =
  fooFuture(input)
  .then(futureA)
  .then(futureB)
  .then(futureC)
  .then(d)
  .then([](OutputD outputD) { // lambdas are ok too
    return outputD * M_PI;
  });

Also provides other compositional building blocks such as collect, map, and reduce. Git repo here. Looks like C++17 may also have support for the .then construct.

Upvotes: 0

1201ProgramAlarm
1201ProgramAlarm

Reputation: 32727

When you create yhmTask you are moving this, which is a pointer. There is no constructor for YHMTask that takes a pointer to a YHMTask so the template specialization fails. You should dereference this before moving it:

YHMTask<decltype(f())> yhmTask(std::move(*this));

Upvotes: 1

Related Questions