Call template function with one or two arguments?

I have situation when i create template function with one argument (component) and sometimes with two (component, gameObject).

template<typename Component, typename F>
    static void CallFunction(GameObject gameObject, F func) {
        // Note: UIFunction should has component as first param and/or gameObject second.
        auto& component = gameObject.GetComponent<Component>();
        constexpr std::size_t args = sizeof...(F);
        if constexpr (args == 1)
            func(component);
        else
            func(component, gameObject);
    }

And i try to use constexpr std::size_t args = sizeof...(F); to get size of arguments of my function and call it with one argument or two. But when im try to use this i get:

C2780 'auto CallFunction::<lambda_06a5858866216a23f9192bc2da910cdc>::operator ()(_T1 &,_T2) const': expects 2 arguments - 1 provided.

How do this properly because im not big fan of templates.


Im removed sizeof...(T) and use std::is_invokable_v for checking that func can be called with some count and type of arguments.

template<typename Component, typename F>
    static void CallFunction(GameObject gameObject, F func) {
        // Note: UIFunction should has component as first param and/or gameObject second.
        auto& component = gameObject.GetComponent<Component>();
        if constexpr (std::is_invocable_v<F, Component>)
            func(component);
        if constexpr (std::is_invocable_v<F, Component, GameObject>)
            func(component, gameObject);
    }

Since C++17 type traits can be used to determine whether the object is invocable accepting some argument types. Small example, change it as needed:

template<typename> inline constexpr bool wrong_func_v = false;

template<typename Component, typename F>
static void CallFunction(GameObject gameObject, F func)
{
    auto& component = gameObject.GetComponent<Component>();
    if constexpr (std::is_invocable_v<F, Component>)
        func(component);
    else if constexpr (std::is_invocable_v<F, Component, GameObject>)
        func(component, gameObject);
    else
        static_assert(wrong_func_v<F>, "wrong param types/count");
}

Then we can use this template:

CallFunction<SomeComponent>(gameObject, one_arg_func);
CallFunction<OrAnotherComponent>(gameObject, two_arg_func);