Variadic template for decuction for member parameter

49 Views Asked by At

I have class that wraps a std::future. He being the result of an async call on a generic function specified by template and the args by a variadic template.

template <class Fn, class... Args>
class AsyncTask {
public:    
    AsyncTask(const Fn& func, Args&&... args)        
        : m_fut(std::async(std::launch::async, func, std::forward<Args>(args)...)){};
    virtual ~AsyncTask(){}
private:
    std::future<typename std::result_of<Fn(Args...)>::type> m_fut;
};

Now I want to pass a member function of one other class to the AsyncTask. This member function will run periodically a generic function. I managed to make it work and you can see the solution here.

class AsyncPeriodicTask {                                                                                                                                                                                    
public:                                                                                                                                                                                                      
     template <class Fn, class... Args>                                                                                                                                                                       
     AsyncPeriodicTask(const std::chrono::milliseconds wait_time, Fn&& inner_func, Args&&... args)                                                                                                            
         : m_stop(false)                                                                                                                                                                                      
         , m_period(wait_time)                                                                                                                                                                                
         , m_task([this, inner_func, tpl = std::make_tuple(std::forward<Args>(args)...)]() { fun(inner_func, tpl); }) {                                                                                       
     }                                                                                                                                                                                                        

     virtual ~AsyncPeriodicTask() { stop(); }                                                                                                                                                                 

     template <class Fn, class... Args>                                                                                                                                                                       
     void fun(Fn&& f, Args&&... args) {                                                                                                                                                                       
        while (!m_stop) {                                                                                                                                                                                    
             std::apply(f, std::forward<Args>(args)...);                                                                                                                                                      
             std::this_thread::sleep_for(m_period);                                                                                                                                                           
         }                                                                                                                                                                                                    
     }                                                                                                                                                                                                        

    void stop() { m_stop = true; }                                                                                                                                                                           

private:                                                                                                                                                                                                     
    std::atomic_bool                m_stop;                                                                                                                                                                  
    const std::chrono::milliseconds m_period;                                                                                                                                                                
    AsyncTask<std::function<void()>> m_task;                                                                                                                                                                 
};                                                  

I found my solution quite ugly and I would like to improve the type and the construction of m_task. Something like:

m_task(&AsyncPeriodicTask::fun, this, inner_func, std::forward<Args>(args)...)

and

using MemberFun = void (AsyncPeriodicTask::*)(int);
AsyncTask<MemberFun, Fn, Args ...> m_task;

I tried many things but I dont get the type. Somebody has a suggestion ?

0

There are 0 best solutions below