将函数和成员函数作为参数传递给另一个函数

Passing functions and member functions as an argument to another function

本文关键字:函数 参数传递 另一个 成员      更新时间:2023-10-16

我编写了一个库,允许通过检查接收到的ASCII字符将函数绑定到键事件。对于在主代码中定义的非成员函数,它可以完美地工作。它对成员函数不起作用。我知道这是因为成员函数和非成员函数是不同类型的。我怎么能传递一个以前未定义的类的函数到这个函数在我的库?

类型定义:

typedef void (*tobind)();

所讨论的函数:

void Keybinder::bind(char key,int mode,tobind func) {
switch(mode){
    //execute depending on the event mode argument
    case 0:
        pressed[key] = func; //assign the function to the character pressed event
        break;
    case 1:
        down[key] = func; //assing the function to the character down event
        break;
    case 2:
        released[key] = func; //assign the function to the character released event
        break;
}
}

如果你正在使用支持c++ 11语法的编译器,那么我建议使用std::function和std::bind方法。

你的typedef应该是这样的:

typedef std::function<void()> tobind;

你可以像这样使用std::bind:

auto func = std::bind(&Foo, arg1, arg2); // non-member usage
auto memFunc = std::bind(&A::MemberFoo, aInstance, arg1, arg2); // member-function usage

如何将先前未定义的类的函数传递给库中的此函数?

您不能使用Keybinder::bind的现有接口。

fwiw,一个有点难看的中间解决方案-如果你的库的绑定方法允许的话-是绑定到static class函数,并将特定的实例作为引用/指针传递(在你的库允许回调的任何"用户数据"中)。static函数能够作为引用实例的friend,从而访问它们的成员,几乎就像它们是自己的一样。

然而,你基本上回到了旧的c风格的'OOP',所以这不是一个非常优雅的方式,如果你有更整洁的替代方案。

我将假设在我使用这种模式的时候,我使用的库不支持任何更好的方式。B -)

use forward declaration + std::bind:

template <class F, class... Args>
    void Keybinder::bind(char key,int mode,F&& f,Args&&... args){
    std::function<void()> callback = std::bind(std::forward<F>(f),std::forward<Args>(args)...);
    //use callback as original func
 }
请注意,非静态成员函数需要传递this指针。
struct Foo{
  void func(){};
};
Foo f;
keybinder.bind('a',4,&Foo::func,&f);