2

As we probably have to wait a bit until std::future::then is implemented I'm trying currently to write a very simple task wrapper the problem is calling the callback function. Lets say we have a class like:

template<typename... ARG>
class Task
{
public:
    typedef std::function<void(ARG...)> task_func_t;

    Task() {}

    void then(task_func_t callback) { this->callback_ = callback; }

    void finish(ARG... arguments)
    {
        this->callback_(std::forward<ARG>(arguments)...);
    }

    void operator()(ARG... arguments)
    {
        this->callback_(std::forward<ARG>(arguments)...);
    }

private:
     task_func_t callback_;
};

and lets assume the following usage:

std::shared_ptr<Task<int>> sum(int n1, int n2)
{
    auto ptr = std::make_shared<Task<int>>();
    myPool.process([n1, n2, ptr]
    {
        (*ptr.get())(n1 + n2);
    }
    return ptr;
}

void test()
{
    sum(5, 6)->then([](int sum) { std::cout << "Sum is " << sum << std::endl };
}

I sometimes have the problem the callback is called before the function is actually set. I know I could check as long as the callback is invalid but I don't really like this solution so are there other smart solutions? I actually thought about doing it like this:

return task.before(do prepare work);

.then(process result)

So then It would call the the create thread when linking is done in then. The perfect solution would be something which calls then before as requirement but I think Its actually impossible as long I want this design.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
Pete
  • 179
  • 11

2 Answers2

1

You could wait on a condition variable. Make it a member of the task class and signal it after setting the function.

cpl
  • 26
  • 3
  • Yes thats the way I've gone for. I hope the overhead wont hurt but It seems like a good way. – Pete Aug 18 '14 at 15:42
1

With future, you may do something like:
(then implementation from implementing-futurethen-equivalent-for-asynchronous-execution-in-c11)

template <typename Fut, typename Work>
auto then(Fut f, Work w) -> std::shared_future<decltype(w(f.get()))>
{
    return std::async([=]{ w(f.get()); });
}

std::shared_future<int> sum(int a, int b)
{
    return std::async([](int a, int b) { return a + b; }, a, b);
}

int main() {
    then(sum(40, 2), [](int n) {std::cout << "Sum is " << n << std::endl;}).wait();
    return 0;
}

Live example

Community
  • 1
  • 1
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • This would block the thread aswell as long get doesnt return. I'm using boost asio I'm developing a http wrapper for it and huge function parameters dont come handy for this I think. And well as I have to wait for the response I have to wait for the answer a long time. I'm suprised how then will be implented. – Pete Aug 18 '14 at 15:41