C++函数模板直接匹配函数指针类型提取参数类型实现方法
实现方案
通过模板偏特化匹配函数指针类型结构,可自动拆分返回值类型与参数类型包,无需构造伪函数指针入参。
代码实现
#include <vector> #include <typeindex> #include <typeinfo> // 主模板声明,接收单个类型参数(传入的目标函数指针类型) template <typename Fn> auto ArgTypes(); // 函数指针类型偏特化实现,自动匹配返回值类型Ret、参数类型包Types template <typename Ret, typename... Types> auto ArgTypes<Ret(*)(Types...)>() { std::vector<std::type_index> vec; vec.insert(vec.end(), {typeid(Types)...}); return vec; }
调用示例
直接传入函数指针类型作为模板参数即可,无需构造中间伪指针对象:
typedef int (*tExampleFn)(int a, bool b, char* c, long long d); auto argTypes = ArgTypes<tExampleFn>();
返回的std::vector<std::type_index>会按函数声明顺序,依次存储int、bool、char*、long long对应的类型索引。
原写法失效原因
初始无参模板的参数列表为template <typename Ret, typename... Types>,显式传入ArgTypes<tExampleFn>()时,编译器仅会将首个模板参数Ret绑定为完整的tExampleFn类型,剩余可变参数包Types为空,无法自动拆分返回值与参数类型。
偏特化版本为编译器提供了明确的匹配规则:当传入的模板参数符合返回值类型(*)(参数列表)的函数指针形态时,自动将对应位置的类型绑定到Ret和Types...。
可选扩展兼容
C++17及以上版本如果需要适配带noexcept标记的函数指针,可追加对应偏特化实现:
// 适配noexcept修饰的函数指针 template <typename Ret, typename... Types> auto ArgTypes<Ret(*)(Types...) noexcept>() { std::vector<std::type_index> vec; vec.insert(vec.end(), {typeid(Types)...}); return vec; }
内容的提问来源于stack exchange,提问作者Stephen Eckels
相关产品推荐
相关产品推荐

