3

我有一个包装 std::future 的类。他是对模板指定的通用函数和可变参数模板指定的参数进行异步调用的结果。

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

现在我想将另一个类的成员函数传递给 AsyncTask。此成员函数将定期运行一个通用函数。我设法让它工作,你可以在这里看到解决方案。

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

我发现我的解决方案非常难看,我想改进 m_task 的类型和构造。就像是:

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

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

我尝试了很多东西,但我没有得到类型。有人有建议吗?

4

0 回答 0