Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::函数,带有定时器C+的成员函数+;_C++_Templates_C++11_Std Function - Fatal编程技术网

C++ std::函数,带有定时器C+的成员函数+;

C++ std::函数,带有定时器C+的成员函数+;,c++,templates,c++11,std-function,C++,Templates,C++11,Std Function,我已经设置了一个计时器类,可以使用std::function模板绑定到自由浮动函数。我想修改该类,使其能够支持使用自由浮动函数和类成员函数。我知道std::function可以使用std::bind绑定到成员函数,但我不知道如何使用我的代码设置它: #include <iostream> #include <chrono> #include <thread> #include <functional> #include <atomic>

我已经设置了一个计时器类,可以使用
std::function
模板绑定到自由浮动函数。我想修改该类,使其能够支持使用自由浮动函数和类成员函数。我知道
std::function
可以使用
std::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;

    };

}
#包括
#包括
#包括
#包括
#包括
名称空间引擎{
模板
班级计时器{
typedef std::function\u function\t;
公众:
计时器(大小\u t间隔、布尔自动运行、\u函数\u t函数、参数…参数){
_功能=功能;
_间隔=间隔;
如果(自动运行){
启用(args…);
}
}
~Timer(){
if(正在运行()){
禁用();
}
}
无效启用(参数…参数){
如果(!Running()){
_运行=真;
启用(_间隔、_函数、参数…);
}
}
无效禁用(){
if(正在运行()){
_运行=错误;
}
}
std::原子布尔常量&Running()常量{
返回运行;
}
受保护的:
无效启用(大小\u t间隔、\u函数\u t func、参数…参数){
_thread=std::thread([&,func,interval,args…])(){
std::chrono::持续时间间隔(间隔);
自动时间间隔=标准时间:微秒(间隔);
自动截止日期=标准::计时::稳定时钟::现在();
当(_运行时){
func(args…);
std::this_thread::sleep_until(截止日期+=_间隔);
}
});
_thread.detach();
}
受保护的:
_函数t函数;
std::原子布尔运行;
大小t间隔;
标准::螺纹_螺纹;
};
}
任何建议都很好。如果我需要澄清什么,请告诉我


感谢

向此传递成员函数,传递指向未绑定成员函数的指针(
&Engine::SceneManager::Update
),然后第一个参数是指向应该调用成员的对象的指针(指向
SceneManager
对象的指针,这是“隐藏的”
指针)。这就是bind的工作原理,因此不需要对代码进行任何更改。作为一个简单的选择,传递一个lambda

(虽然它没有按预期运行,我也不知道为什么)


此外,我还对以下事实感到困惑:您的代码将interal作为大小,然后将其转换为纳秒,然后将其转换为微秒,然后使用它。为什么不在整个过程中使用微秒

你的析构函数有一个竞态条件。禁用应该暂停,直到线程完成执行。我没有太多地使用
std::thread
,但我想应该从
if(_-thread.is_-joinable())\u-thread.join()开始作为其中的一部分,让线程一次只休眠100毫秒左右可能很有用,并定期检查它是否应该关闭


Enable
应在启动新线程之前停止现有线程。更好的是,重用相同的线程。不幸的是,现有的线程切换任务没有简单的方法,因此最简单的方法是禁用现有的代码,然后保留现有的代码。

您的代码看起来很好,并且似乎能够绑定到成员函数。为什么你认为有问题?@MooingDuck当我声明timer
Engine::timer f(16667,true,Engine::SceneManager::Update)时就像
Engine::SceneManager::Update
是成员函数一样,我得到错误“调用无对象参数的非静态函数”该函数是
&Engine::SceneManager::Update
,第一个参数是指向调用
Update
SceneManager
的指针。这是一个关于
bind
的问题,而不是关于您的代码。(虽然它没有按预期运行,我也不知道为什么)@MooingDuck谢谢你的帮助。时间单位的问题只是我还没有清理干净的问题,我计划调整它。看了你贴的代码后,我把它绑定了。至于禁用功能。你有什么建议来修复比赛状态?你有什么建议来防止比赛状态?@AlexZywicki:再详细一点。这正是我修复比赛状态所做的。我将门更改为
if(_-thread.joinable()){u-thread.join();}
,然后删除了阻止线程连接的行
\u-thread.detach()