我有一个计时器类,我已将其设置为能够使用 std::function
模板绑定(bind)到自由 float 函数。我想修改类以支持使用自由 float 函数和类成员函数。我知道 std::function
可以使用 std::bind
绑定(bind)到成员函数,但我不确定如何使用我的代码进行设置:
#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
#include <atomic>
namespace Engine {
template<class return_type,class...arguments>
class Timer{
typedef std::function<return_type(arguments...)> _function_t;
public:
Timer(size_t interval,bool autoRun,_function_t function,arguments...args){
_function = function;
_interval = interval;
if (autoRun) {
Enable(args...);
}
}
~Timer(){
if (Running()) {
Disable();
}
}
void Enable(arguments...args){
if (!Running()) {
_running=true;
enable(_interval, _function, args...);
}
}
void Disable(){
if (Running()) {
_running=false;
}
}
std::atomic_bool const& Running()const{
return _running;
}
protected:
void enable(size_t interval,_function_t func,arguments...args){
_thread =std::thread([&,func,interval,args...](){
std::chrono::duration<long long,std::nano> inter(interval);
auto __interval = std::chrono::microseconds(interval);
auto deadline = std::chrono::steady_clock::now();
while (_running) {
func(args...);
std::this_thread::sleep_until(deadline+=__interval);
}
});
_thread.detach();
}
protected:
_function_t _function;
std::atomic_bool _running;
size_t _interval;
std::thread _thread;
};
}
任何建议都会很棒。如果我需要澄清任何事情,请告诉我。
谢谢
最佳答案
要给this传递一个成员函数,传递一个指向未绑定(bind)成员函数的指针(&Engine::SceneManager::Update
),然后第一个参数是指向应该有的对象的指针调用的成员(指向 SceneManager
对象的指针,这是“隐藏的”this
指针)。这就是 bind 的工作方式,因此您的代码无需更改。作为一种简单的替代方法,传递一个 lambda。
http://coliru.stacked-crooked.com/a/7c6335d4f94b9f93 (虽然它没有按预期运行,我也不知道为什么)
此外,我对您的代码将 interal 作为 size_t,然后将其转换为纳秒,然后将其转换为微秒,然后使用它这一事实感到困惑。为什么不在整个过程中只使用微秒呢?
你的析构函数有竞争条件。禁用应该停止,直到线程完成执行。我没怎么用过 std::thread
,但我想可以从 if (_thread.is_joinable()) _thread.join();
开始其中的一部分,让线程一次只休眠 100 毫秒左右并定期检查它是否应该关闭可能很有用。
Enable
应该在启动新线程之前停止现有线程。更好的是,重用同一个线程。不幸的是,没有简单的方法来执行现有的线程切换任务,因此最简单的方法是简单地禁用
然后保留现有代码。
关于c++ - 带有定时器 C++ 成员函数的 std::function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23900403/