如何创建一个函数,它以任意函数指针作为参数?

How can you make a function that takes as a parameter an arbitrary function pointer?

我正在尝试执行以下操作,我什至不确定是否可行。

我想要一个接受任意函数指针并将其传递给不同函数的函数(我知道这是一种代码味道,良好的软件工程实践不是我现在想讨论的)。

换句话说,我正在寻找的东西看起来像:

void method1(arbitraty pointer p)
{
    method2(p);
}

我不确定是否有办法声明任意函数指针(return 值保证为 void 但参数是任意的,无论是数量还是类型)​​

这可能被某些人认为是过度设计,但您可以尝试以下操作:

为您感兴趣的每个回调创建一个枚举:

enum GlfwCallback {
    KeyCallback,
    FramebufferSizeCallback,
    // etc.
};

然后创建一个类型族,将其中的每一个与相应的函数指针类型相关联。通过创建一个模板结构并反复特化它来做到这一点:

template<GflwCallback callback>
struct GlfwCallbackType {};

template<>
struct GlfwCallbackType<KeyCallback> {
    using CallbackType = GLFWkeyfun;
    // or
    using CallbackType = void(*)(GLFWwindow *, int, int, int, int);
};

template<>
struct GlfwCallbackType<FramebufferSizeCallback> {
    using CallbackType =  GLFWframebuffersizefun;
};

// etc.

那你就可以写

template<GlfwCallback callback>
void method1(GlfwCallbackType<callback>::CallbackType p) {
    // do something with p
    method2<callback>(p);
};

另外请注意,您可以根据应用程序的需要向 "type family" 添加其他类型甚至静态函数和数据成员。

一种做你想做的事情的可能性,但以一种很好的、​​类型安全的方式,将是使用函子,即 class 为 operator() 定义重载的对象。
由于仿函数是 class,您可以将参数设置为数据成员,并将要作为任意指针传递的函数的 implementation/calling 移动到 operator() 方法中,您可以在其中拥有通过 this 指针访问所有参数。

此外,您可以定义一个函子层次结构,每个函子都有专门的参数和实现,因此您可以像下面这样修改 method2 的签名:

method2(BaseFunctor* myfunctor) {
   if (myfunctor) 
      (*myfucntor)();
} 

并在调用上下文中设置正确类型的仿函数对象。

另请查看 lambdas (c++11),它基本上是函子定义的快捷方式。

仅当推导的类型是函数指针类型时,使用模板并使用 SFINAE 启用它:

template <typename T, std::enable_if_t<std::is_function<T>::value, int> = 0>
void method1(T* p)
{
    // ...
}