首页 > 解决方案 > 如何将各种功能绑定到计时器?

问题描述

我有一个简单的计时器,我想在固定时间后执行我的功能。

代码是:

#include <thread>
typedef void (*callback)();
class timer {
 public:
   virtual ~timer() {
     t_.join();
   }
   void start(int sec, callback f) {
     if (t_.joinable()) t_.join();
     t_ = std::thread([sec, &f]() {sleep(sec); f();});
   }
  std::thread t_;
};

void test () {
  printf("here called\n");
}
int main() {
  timer t;
  t.start(3, test);  // TODO: test is ok, but it wont work
  // if test is a class member function, or it have parameters.
  while (1);
}

如果我的函数是全局非参数函数,则可以使用。

但是当我使用类成员函数(不是静态的)时,我认为它不会工作。

那么,如果我希望我的函数有参数并且可能是类成员函数,你能帮忙吗?

标签: c++c++11

解决方案


我们可以使用start带有模板参数的函数来替换函数指针参数

#include <chrono>
#include <functional>
#include <iostream>
#include <thread>
class timer {
 public:
  virtual ~timer() { t_.join(); }
  template <typename Fn>
  void start(std::chrono::seconds sec, Fn&& f) {
    t_ = std::thread([sec, f = std::move(f)]() {
      std::this_thread::sleep_for(sec);
      f();
    });
  }
  std::thread t_;
};

void test() { printf("here called\n"); }

class A {
 public:
  void test(int arg) {
    std::cout << "a member function with arg:" << arg << '\n';
  }
};

int main() {
  timer t;
  auto sec(std::chrono::seconds(1));
  t.start(sec, test);

  timer t1;
  t1.start(sec, []() { std::cout << "lambda\n"; });

  timer t2;
  auto a_ptr = std::make_shared<A>();
  t2.start(sec, std::bind(&A::test, a_ptr, 1));

  timer t3;
  t3.start(sec, [] {
    A a;
    a.test(1);
  });

  return 0;
}

在线演示


推荐阅读