You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>时,编译器会自动完成类型推导:

  1. 主模板的参数是void(*)()类型的函数指针,但&foo的实际类型是void(*)(int),不直接匹配主模板;
  2. 编译器会查找适配的部分特化版本,发现特化模板的参数void(*Func)(T)正好和&foo的类型匹配;
  3. 编译器自动推导出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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:47:39