Следующее будет работать для любой арности, но принимать произвольные типы аргументов:
template <typename T>
struct arity
{
};
template <typename... Args>
struct arity<std::function<Foo(Args...)>>
{
static const int value = sizeof...(Args);
};
Если вы действительно хотите ограничить ваш тип аргумента функциями типа Foo(Bar, Bar, ...)
, то вы можете сделать что-то вродеthis:
template <typename T>
struct arity
{
};
template <typename... Args>
struct const_tuple
{
};
template <>
struct const_tuple<>
{
struct unsupported_function_type { };
};
template <typename... Args>
struct const_tuple<Bar, Args...>
{
typedef typename const_tuple<Args...>::unsupported_function_type unsupported_function_type;
};
template <typename... Args>
struct arity<std::function<Foo(Args...)>> : public const_tuple<Args...>::unsupported_function_type
{
static const int value = sizeof...(Args);
};
Это даст вам ошибку компиляции всякий раз, когда вызывается arity с неподдерживаемым типом функции.