c++templatestraitsc++20

Get pointer to overloaded function that would be called


Please refer to the following:

struct functorOverloaded
{
    void operator()(const int& in_, ...) const {}
    void operator()(short in_) {}
};

// helper to resolve pointer to overloaded function
template <typename C, typename... OverloadArgs>
auto resolve_overload(
    std::invoke_result_t<C, OverloadArgs...> (C::* func)(OverloadArgs..., ...) const
)
{ return func; };


int main(int argc, char **argv)
{
    using C = const functorOverloaded;

    // works with exact function type
    using myT = decltype(resolve_overload<C, const int&>(&C::operator()));
    // can call with something convertible to const int&
    static_assert(std::is_invocable_v<C,int>, "!!!");
    // how to get the pointer to the overload that would be called when passed int (or double)?
    // the next line doesn't compile (error C2672: 'resolve_overload': no matching overloaded function found)
    using myT2 = decltype(resolve_overload<C, int>(&C::operator()));
   
    return 0;
}

The above code allows retrieving a pointer to a specific overload of a function (operator() in this case), see here. One must know the exact argument type (const int&) in this case to get the pointer, even though i can just call the specific overload with a plain int, or even double. Is it possible to get a pointer to the overload that would be called with the specific argument (assuming the call is resolvable / not ambiguous)?


Edit: adding context:

I am writing a invocable_traits library for introspecting a callable. E.g., given a Callable, it will tell you the return type, arity and argument types, amongst some other properties. To support functors (including lambdas) with overloaded (or templated) operator(), the API of invocable_traits allows specifying call arguments to disambiguate which overload is to be used (or to instantiate the template). However, one must know the exact argument type (const int& in the example above), simply specifying int won't do in that case as there is no function with signature R operator()(int). Ideally, I'd like to allow discovering the signature of the exact overload/instantiation that gets called given the provided input argument types, ideally even taking into account any implicit conversions that are applied. Is this possible?


Solution

  • There is no way to get the function of an overload-set which would be called with the given arguments, unless you already know its signature.
    And if you know, what's the point?

    The problem is that for any given arguments, taking into account implicit conversions, references, cv-qualifiers, noexcept, old-style vararg, default arguments, and maybe also literal 0 being a null pointer constant, there are an infinite number of function-signatures which would match. And there is currently no facility for "just" listing all candidates.