У меня есть класс, который оборачивает 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;
Я пробовал много вещей, но я не получил тип. У кого-нибудь есть предложение?