这里有一些方法;都假设 C++11。使用 -std=c++11 在 clang++ 3.2 上测试。
//Taking a function pointer argument (template types inferred)
template <typename ret, typename ... Args>
constexpr int arg_count(ret (*f)(Args...)) {
return sizeof...(Args);
}
//Taking a function type (or related) directly
template <typename T>
struct ArgCount {
static const int value = 0;
};
template <typename Ret, typename ... Args>
struct ArgCount<Ret(Args...)> {
static const int value = sizeof...(Args);
};
template <typename Ret, typename ... Args>
struct ArgCount<Ret(*)(Args...)> {
static const int value = sizeof...(Args);
};
template <typename Ret, typename ... Args>
struct ArgCount<Ret(&)(Args...)> {
static const int value = sizeof...(Args);
};
//Using the latter for dispatch
template <int N>
struct helper {
template<typename F, typename T1, typename T2>
static void call(F func, T1 t1, T2 t2);
};
template <>
struct helper<1> {
template<typename F, typename T1, typename T2>
static void call(F func, T1 t1, T2 t2) {
func(t1);
}
};
template <>
struct helper<2> {
template<typename F, typename T1, typename T2>
static void call(F func, T1 t1, T2 t2) {
func(t1, t2);
}
};
template<typename F, typename T1, typename T2>
void my_magic_method(F func, T1 t1, T2 t2)
{
helper<ArgCount<F>::value>::call(func, t1, t2);
}
//Testing
#include <cstdio>
void a(int a, int b) { printf("%i\n", a + b); }
void b(int x) { printf("%i\n", x); }
int main() {
printf("%i %i\n", arg_count(a), arg_count(b));
printf("%i %i\n", ArgCount<decltype(a)>::value, ArgCount<decltype(b)>::value);
my_magic_method(a, 1, 2);
my_magic_method(b, 1, 2);
}