【问题标题】:Use methods as callback in C++ in a convenient way以方便的方式在 C++ 中将方法用作回调
【发布时间】:2015-02-21 19:55:06
【问题描述】:

我想使用方法作为回调。我知道有一种非常通用的语法允许使用任何类型的可调用作为回调:

void f(int x) { cout << "f("<<x<<")" << endl; }

class C
{
public:
   void m(int x) { cout << "C::m("<<x<<")" << endl; }
};

class C2
{
public:
   void registerCallback(function<void(int)> f)
   {
      v.push_back(f);
   }

private:
   vector<function<void(int)>> v;

   void callThem()
   {
      for (int i=0; i<v.size(); i++)
      {
         v[i](i);
      }
   }
};

int main()
{
   C2 registrar;

   C c;
   registrar.registerCallback(&f); // Static function
   registrar.registerCallback(bind(&C::m, &c, placeholders::_1)); // Method

   getline(cin, string());

   return 0;
}

请注意,必须可以将任何类的方法注册为回调。

但是我想允许以下更方便的语法来注册方法:

registrar.registerCallback(&C::m, c); // Method

是否可以提供registerCallback() 重载,允许更基本的语法,而无需在注册方法时使用bind

【问题讨论】:

  • 您是否尝试过重载registerCallback,这是一个将调用std::bind 的结果传递给registerCallback 的当前实现的模板?
  • 没有。我会试试看。那么没有绑定就没有明智的方法来实现吗?
  • 根据您要完成的工作std::bind 似乎是构造函数对象的最明智的方式。

标签: c++ c++11 methods callback


【解决方案1】:

如果你想要那种语法,我想你可以很容易地将它包装在一个重载中:

   template <typename Func, typename Obj>
   void registerCallback(Func f, Obj& obj)
   {
      registerCallback(bind(func, &obj, placeholders::_1));
   }

【讨论】:

    【解决方案2】:

    如果你只是反对bind,你也可以使用 lambda:

    registrar.registerCallback([&c](int x){c.m(x);});
    

    注意:注意这一点,我在这里使用了对 c 的引用,如果它的生命周期比 registrar 短,如果你尝试调用该函数,则会出现段错误。

    【讨论】:

      【解决方案3】:

      你想要一个类方法的重载:

      template <typename Class>
      void registerCallback(void (Class::*method)(int ), Class& object)
      {
          // just forward to the generic one
          registerCallback([=](int x){ (object.*method)(x); });
      
          // or bind it
          registerCallback(std::bind(method, &object, std::placeholders::_1));
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-12
        • 2018-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多