c++functionc++11c++14arity

Get function arity from template parameter


How can I get the arity of an arbitrary function type used as a template parameter?

The function can be a normal function, a lambda or a functor. Example:

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
}

I have access to all C++14 features.

Do I have to create specialization for every function type (and all respective qualifiers)? Or is there an easier way?


Solution

  • Assuming that all the operator()'s and functions we're talking about are not templates or overloaded:

    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
    

    Demo.