如何在C++17/C++20中按参数数量获取重载成员函数指针
实现通用的参数数量匹配重载函数指针获取工具
在C++17及以上标准中,完全可以通过可变参数模板结合编译期检查,实现无需逐个特化的Overload模板,避免重复编写不同参数数量的特化代码。
核心实现方案
利用可变参数模板接收任意参数列表,再通过编译期条件筛选出参数数量与Num匹配的版本。以下是C++17兼容的实现:
#include <type_traits> template<int Num> struct Overload { // 匹配普通函数指针 template<class Ret, class... Args> static auto from(Ret (*func)(Args...)) -> std::enable_if_t<sizeof...(Args) == Num, decltype(func)> { return func; } // 匹配非const成员函数指针 template<class Ret, class Class, class... Args> static auto from(Ret (Class::*meth)(Args...)) -> std::enable_if_t<sizeof...(Args) == Num, decltype(meth)> { return meth; } // 匹配const成员函数指针 template<class Ret, class Class, class... Args> static auto from(Ret (Class::*meth)(Args...) const) -> std::enable_if_t<sizeof...(Args) == Num, decltype(meth)> { return meth; } };
C++20优化版本
如果使用C++20,可以用requires表达式替代enable_if,代码可读性更好:
template<int Num> struct Overload { // 匹配普通函数指针 template<class Ret, class... Args> static auto from(Ret (*func)(Args...)) requires (sizeof...(Args) == Num) { return func; } // 匹配非const成员函数指针 template<class Ret, class Class, class... Args> static auto from(Ret (Class::*meth)(Args...)) requires (sizeof...(Args) == Num) { return meth; } // 匹配const成员函数指针 template<class Ret, class Class, class... Args> static auto from(Ret (Class::*meth)(Args...) const) requires (sizeof...(Args) == Num) { return meth; } };
使用示例
针对你提供的Test类,获取指定参数数量的重载版本非常简洁:
struct Test { int func(int i1); int func(int i1, int i2); int func(int i1, int i2, int i3); }; // 获取2个参数的成员函数指针 auto two_arg_func = Overload<2>::from(&Test::func); // 获取1个参数的成员函数指针 auto one_arg_func = Overload<1>::from(&Test::func);
补充说明
这个实现完全满足你的需求:
- 无需为每个参数数量编写单独的特化代码,一次实现适配所有非负整数
Num - 与你现有的
OverloadArgs互补,既支持按参数数量选择重载,也支持按参数类型选择 - 兼容普通函数、非const成员函数、const成员函数三种场景,满足Python绑定的需求
内容的提问来源于stack exchange,提问作者maxbachmann
相关产品推荐
相关产品推荐

