Получить функцию арности из параметра шаблона

Как я могу получить арность произвольного типа функции, используемого в качестве параметра шаблона?

Функция может быть нормальной функцией, лямбда или функтором. Пример:

template<typename TFunc>
std::size_t getArity()
{
// ...?
}

template<typename TFunc>
void printArity(TFunc mFunc)
{
std::cout << "arity: " << getArity<TFunc>() << std::endl;
}

void testFunc(int) { }

int main()
{
printArity([](){}); // prints 0
printArity([&](int x, float y){}); // prints 2
printArity(testFunc); // prints 1
}

У меня есть доступ ко всем функциям C ++ 14.

Нужно ли создавать специализацию для каждого типа функции (и всех соответствующих классификаторов)?
Или есть более простой способ?

9

Решение

Предполагая, что все operator()и функции, о которых мы говорим, не являются шаблонами или перегружены:

template <typename T>
struct get_arity : get_arity<decltype(&T::operator())> {};
template <typename R, typename... Args>
struct get_arity<R(*)(Args...)> : std::integral_constant<unsigned, sizeof...(Args)> {};
// Possibly add specialization for variadic functions
// Member functions:
template <typename R, typename C, typename... Args>
struct get_arity<R(C::*)(Args...)> :
std::integral_constant<unsigned, sizeof...(Args)> {};
template <typename R, typename C, typename... Args>
struct get_arity<R(C::*)(Args...) const> :
std::integral_constant<unsigned, sizeof...(Args)> {};

// Add all combinations of variadic/non-variadic, cv-qualifiers and ref-qualifiers

демонстрация.

7

Другие решения