Я получил эту функцию, которая нуждается в ссылке на функцию:
template <typename Fn>
void Caller::operator()(const Fn& funct, bool*is_running, int time_sec)
{
//Some code
funct();
}
И я называю это так:
auto t = make_timer(DataHandler::dh().send, Data::sendPeriod);
Функция отправки находится в классе DataHandler, я использую статический экземплярdh:
static DataHandler& dh(){static DataHandler dh = DataHandler(); return dh;}
Возвращает ошибку:
error: must use '.*' or '->*' to call pointer-to-member function in 'funct (...)', e.g. '(...->* funct) (...)'
Он говорит, что требуется от main, где я его называю.
Кто-нибудь знает, в чем может быть проблема?
Минимальный, полный и проверяемый пример:
#include <iostream>
#include "timer.h"
class DataHandler{
public:
static DataHandler& dh(){static DataHandler dh = DataHandler(); return dh;}
DataHandler(){};
void send(){std::cout << "send";}
};
int main()
{
auto t = make_timer(DataHandler::dh().send, 20);
return 0;
}
И timer.h, хотя я не знаю, как его сократить: (
#include <thread>
#include <functional>
struct Caller
{
template<typename Fn>
void operator()(const Fn& funct, bool*is_running, int time_sec);
};
template <typename Fn>
class Timer
{
protected:
std::thread timer_thread;
bool is_running;
public:
Timer(Fn fn, int time_sec);
Timer(const Timer&) = delete;
Timer(Timer&& timer);
void stop();
~Timer();
};
template <typename Fn>
void Caller::operator()(const Fn& funct, bool*is_running, int time_sec)
{
do
{
std::this_thread::sleep_for(std::chrono::milliseconds(time_sec*1000));
funct();
} while(*is_running);
}
template <typename Fn>
Timer<Fn>::Timer(Fn fn, int time_sec)
:
is_running(true)
{
Caller caller{};
auto proc = std::bind(caller, fn, &(this->is_running), time_sec);
std::thread tmp(proc);
swap(this->timer_thread, tmp);
}
template <typename Fn>
Timer<Fn>::Timer(Timer&& timer)
:
timer_thread(move(timer.timer_thread)),
is_running(timer.is_running)
{
}
template <typename Fn>
void Timer<Fn>::stop()
{
if(this->is_running)
this->is_running = false;
}
template <typename Fn>
Timer<Fn>::~Timer()
{
//this->stop();
timer_thread.join();
}
template<typename Fn>
Timer<Fn> make_timer(Fn fn, int time)
{
return Timer<Fn>{fn, time};
}