C++98环境下如何从函数指针静态推断函数参数类型?
解决方案:利用模板部分特化静态提取函数指针参数类型
当然可以做到!在C++03标准下,你不需要显式指定模板参数T,通过模板部分特化就能从函数指针中静态提取出参数类型。下面是具体实现:
// 主模板:仅声明,用于匹配函数指针类型的非类型模板参数 template <void(*Func)()> struct A; // 部分特化版本:专门匹配"void(*)(T)"类型的一元函数指针 template <typename T, void(*Func)(T)> struct A<Func> { typedef T arg_t; };
工作原理
当你写A<&foo>时,编译器会自动完成类型推导:
- 主模板的参数是
void(*)()类型的函数指针,但&foo的实际类型是void(*)(int),不直接匹配主模板; - 编译器会查找适配的部分特化版本,发现特化模板的参数
void(*Func)(T)正好和&foo的类型匹配; - 编译器自动推导出
T为int,于是A<&foo>::arg_t就被定义为int,全程不需要你显式指定类型。
使用示例
结合你的共享库函数,测试一下:
extern "C" void foo(int); extern "C" void zoo(double); // 静态提取参数类型 typedef A<&foo>::arg_t FooArgType; // FooArgType == int typedef A<&zoo>::arg_t ZooArgType; // ZooArgType == double
扩展说明
如果你的共享库还有其他签名的函数(比如带返回值、多参数),只需要添加对应的部分特化即可。比如针对返回值为R、单参数T的函数:
// 主模板扩展为通用函数指针匹配 template <typename FuncPtr> struct FuncTraits; // 特化:返回值R,单参数T的函数指针 template <typename R, typename T> struct FuncTraits<R(*)(T)> { typedef R return_type; typedef T arg_type; }; // 基于通用特性模板实现你的结构体A template <typename FuncPtr> struct A { typedef typename FuncTraits<FuncPtr>::arg_type arg_t; }; // GCC下可借助typeof简化类型传递(C++03无标准decltype) typedef A<typeof(&foo)>::arg_t FooArg;
不过针对你当前的需求(void返回值的一元函数),第一种特化方案已经完全满足,而且不需要任何编译器扩展,纯标准C++03即可运行。
内容的提问来源于stack exchange,提问作者Fabio
相关产品推荐
相关产品推荐

