std :: function与Timer C ++的成员函数

时间:2014-05-27 23:12:24

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

我有一个我设置的计时器类,可以使用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;

    };

}

任何建议都会很棒。如果我需要澄清任何内容,请告诉我。

由于

1 个答案:

答案 0 :(得分:2)

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

http://coliru.stacked-crooked.com/a/7c6335d4f94b9f93(虽然没有按预期运行,我不知道为什么)

<小时/> 另外,我很困惑你的代码将interal作为size_t,然后将其转换为纳秒,然后将其转换为微秒,然后使用它。为什么不直接使用微秒?

你的析构函数有竞争条件。禁用应该停止,直到线程执行完毕。我没有多少使用this,但我猜一个地方是std::thread作为其中的一部分,让线程一次只能睡100ms可能是有用的,并定期检查是否应该关闭。

if (_thread.is_joinable()) _thread.join();应该在开始新线程之前停止现有线程。更好的是,重用相同的线程。不幸的是,现有的线程切换任务没有简单的方法,所以最简单的方法就是Enable,然后保留现有的代码。