以方便的方式在C ++中使用方法作为回调

时间:2014-12-23 16:32:06

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

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

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

3 个答案:

答案 0 :(得分:2)

如果您想要这种语法,我认为您可以轻松地将其包装在重载中:

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

答案 1 :(得分:1)

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

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

注意:请注意这一点,如果您的生命周期短于c,我在registrar使用{{1}},如果您尝试调用该函数,则会出现段错误。

答案 2 :(得分:0)

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

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));
}