Since the type of a non-static member function is an ordinary function type and since we can't use decltype on a non-static member function to get its type, I propose that we should add a trait to get back the type of a non-static member function.

The following is the first draft(crude) example of what I am suggesting. Also this topic of getting back the type of a non-static member function seems to be a fairly common question on sites like stackoverflow and looking at those question I notice that almost all of them tries to use decltype first to solve this problem but then came to realise that, using decltype for like this is not allowed. So this trait might provide a standard way of getting back the "ordinary function type" associated with the non-static member function.

struct C
{
    void Func(std::string, int) const;
    void Bar(int);
};
template<typename T, typename Ret, typename... Args>
struct GetType
{
    using type = Ret(Args...);
    GetType(Ret (T::*)(Args...) const) 
    {

    }
    GetType(Ret (T::*)(Args...) ) 
    {

    }
};

int main()
{
    using ret1 = decltype(GetType(&C::Func))::type; // void(std::string, int) as expected
    using ret2 = decltype(GetType(&C::Bar))::type;  //void(int)               as expected 
}
[Demo](https://godbolt.org/z/rd49WW8ef)

----------------------------------------

Note that I usually use CTAD for this kind of problem as it reduces writing some extra code. Also this is just a demo to show the overall idea of what I am proposing. I realise that in order for this to work with potentially all non-static member functions(with any type), we might have to modify it as needed.

Regards,
Anoop Rana
M.Sc Applied Physics