C函数与C ++方法的回调

时间:2015-07-30 12:29:46

标签: c++ callback

我有一个带有bar()方法的Foo类。 我也有一个bar2()函数(在任何类之外) 还有一个Xpto类,我需要用一些回调来设置构造函数。

class Foo
{
  //...
  public:
     bar()
     {
       //do stuff..
     }
  //...
}

//isolated C function outside class
void bar2()
{
}

class Xpto
{
  //...
  public:
     Xpto(std::function<void()> &callback)
     {
       //do stuff..
     }
  //...
}

int main()
{
   Xpto x1(bar2); // <---- compiles

   Foo myFoo;
   Xpto x2(myFoo.bar); // <--- doesn't compile

   return 0;
}

为什么我可以使用Foo对象的回调方法创建Xpto对象?

4 个答案:

答案 0 :(得分:3)

因为myFoo.bar的签名不等于std::function<void()>(因为它的成员函数)。您可以使用std::bind(并查看使用成员函数指针的正确语法)。

Xpto x2(std::bind(&Foo::bar, std::ref(myFoo)));

答案 1 :(得分:2)

如果你想要使用方法,你应该使用它的签名,如:

class Xpto
{
  //...
  public:
     template <class T>
     Xpto(void (T::* func)())
     {
       //do stuff..
     }

     Xpto(std::function<void()> &callback)
     {
       //do stuff..
     }
  //...
}

这一行void (T::* func)()表示你将接受一个返回void的方法,并且不接受来自objetc T的参数作为参数。

并使用那样:

Xpto x2(&myFoo::bar);

答案 2 :(得分:1)

您正在使用Xpto x1(bar2);的隐式转换。它正在调用std::function<void()>的隐式构造函数来从bar2创建一个。

在第二种情况下,您提供的成员函数没有void()的签名。如果是void Foo:*()(指向成员函数的指针)。

要工作,您必须使用std::bind,如下所示:

Xpto x2(std::bind(&Foo::bar, myFoo));

答案 3 :(得分:1)

因为没有myFoo.bar的{​​{1}}实际上并不是一个合法的C ++表达式(尽管这样的事情在python中是完全有意义的),而()只是指向返回bar2的无效函数的指针,该函数可转换为void

引用成员函数的正确方法是std::function<void()>,然后您还需要提供&Foo::bar的实例。你可以做其中一个:

Foo

另请注意,通常您想要Xpto x2(std::bind(&Foo::bar, myFoo)); Xpto x2([myFoo]{ myFoo.bar(); }); 采用arguemnts。更喜欢将构造函数编写为:

std::function<Sig>