我有一个模板。
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)...);
}
根据业务员的要求进行更新
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::function
的,需要手动通过 std::function
的其他可调用函数。
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);
}