AAAA
AAAA

Reputation: 512

Schedule event later in C++: how to pass the task to be ran

I'm trying to run the following codes to schedule taskFun in class A to start running after 1000ms. When I run this code, I get this error:

main.cpp:9:70: error: no type named 'type' in 'std::__1::result_of<void (A::*(int))(int)>'
    std::function<typename std::result_of < callable(arguments...)>::type() > task(std::bind(std::forward<callable>(f), std::forward<arguments>(args)...));
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
main.cpp:29:10: note: in instantiation of function template specialization 'later<void (A::*)(int), int>' requested here
         later(1000, true, &A::taskFun, 101);
     ^

I don't get this error if I define taskFun as a static function. But I don't want it to be static. Is there any way to update 'later' function to accept non-static inputs?

    #include <functional>
    #include <chrono>
    #include <future>
    #include <cstdio>
    #include <iostream>
    
    template <class callable, class... arguments>
    void later(int after, bool async, callable f, arguments&&... args) {
        std::function<typename std::result_of < callable(arguments...)>::type() > task(std::bind(std::forward<callable>(f), std::forward<arguments>(args)...));
    
        if (async) {
            std::thread([after, task]() {
                std::this_thread::sleep_for(std::chrono::milliseconds(after));
                task();
            }).detach();
        } else {
            std::this_thread::sleep_for(std::chrono::milliseconds(after));
            task();
        }
    }
    


    class A {
    public:
    
        A() {
        }
    
        void callLater() {
            later(1000, true, &A::taskFun, 99);
        }
    
        void taskFun(int a) {
            std::cout << a << "\n";
        }
    
    };

Upvotes: 1

Views: 809

Answers (1)

Asteroids With Wings
Asteroids With Wings

Reputation: 17454

You were close.

As a non-static member function, taskFun has a hidden argument which becomes this. You need to bind this to the callback in addition to your argument 99:

later(1000, true, &A::taskFun, this, 99);

Now the argument list matches.

A lambda would probably be nicer though:

later(1000, true, [=]() { taskFun(99); });

If you stick to this approach, you can get rid of the std::function and the arguments parameter pack from later.

Upvotes: 1

Related Questions