如何在函数指针中模板化参数?

How to template a parameter in function pointer?

我有一个模板:

template<typename T>
void testFuction(int(*testFunc)(CallBack, void *, T *))
{
    // define CallBack callback, void* param1, T* param2
    // ...
    testFunc(callback, param1, param2);
}

它有效,但看起来很糟糕, 我想做类似的事情:

template<typename T>
// using TestFunc<T> = std::function<int(CallBack, void *, T *)>
void testFuction(TestFunc<T> testFunc)
{
   // define CallBack callback, void* param1, T* param2
   // ...
   testFunc(callback, param1, param2);
}

但是不行。

有人可以帮我吗? 我还用一些添加的参数重载了许多类似的函数,它们看起来很难看。 我想定义一次 TestFunc<T> 并在模板函数中再次使用它。

您可以为模板化函数指针提供类型别名,如下所示

#include <utility> // std::forward

template<typename T>
using FunPointerT = int(*)(CallBack, void*, T*);

template<typename T, typename... Args>
void testFuction(FunPointerT<T> funcPtr, Args&& ...args)
{
   // variadic args, in the case of passing args to testFuction
   funcPtr(std::forward<Arg>(args)...);
}

根据 Op 的要求更新

template<typename T> 
void testFuction(FunPointerT<T> funcPtr) 
{
   // ...
   funcPtr(/* args from local function scope */);
}

让我们看一个简化的例子:

#include <functional>

template<typename T>
void test_function(std::function<void(T*)> f) {
    f(nullptr);
}

void use_int_ptr(int* i);

int main() {
    test_function(use_int_ptr);
}

编译失败:T不能推导为int。它与 void (*f)(T*) 一起工作的原因是 T 可以 如果传递一个函数指针,但函数指针不是 std::function

您有几个可能的解决方案。您可以手动指定 T:

test_function<int>(use_int_ptr);

您可以传递一个 std::function,这样就可以推导出 T

test_function(std::function<void(int*)>{use_int_ptr});
// Or in C++17 with CTAD
test_function(std::function{use_int_ptr});

制作一个转发函数,将函数指针包装在 std::functions 中,如上,需要手动传递 std::functions 给其他可调用对象:

template<typename T>
void test_function(void f(T*)) {
    test_function(std::function<void(T*)>{f});
}

或者只需在原始函数中采用任何类型:

template<typename F>
void test_function(F&& f) {
    f(nullptr);
}