c++ - 带有定时器 C++ 成员函数的 std::function

标签 c++ templates c++11 std-function

我有一个计时器类,我已将其设置为能够使用 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/

相关文章:

c++ - Qt - 编写一个多 TCP 服务器程序

c++ - 如何在模板中为类型引入名称别名

c++ - 使用指数对大数进行 Double 到 String 的转换

c++ - C中结构体中使用的函数指针

c++ - WaitForSingleObject 给出无效句柄

c++ - 为什么从 void 函数模板返回时没有出现编译器错误?

c++ - 为什么在推导类型时去除模板参数的限定符?

c++ - 转发引用和模板模板

c++ - 作者在解释 C++ 中的堆栈和堆时是否犯了错误,或者我误读了什么?

c++ - std::dynarray 与 std::vector