Despite @MRB's working answer , there is a more compact solution.
This follows a minimal working example:
#include<iostream> struct Foo { double bar(double n, double m) {} int bar(int n, int m) {} }; double quux(double n, double m) {} int quux(int n, int m) {} template<typename... A, typename T, typename R> constexpr auto find_overload(R(T::*f)(A...)) { return f; } template<typename... A, typename R> constexpr auto find_overload(R(*f)(A...)) { return f; } int main() { auto fooAddressDouble = find_overload<double, double>(&Foo::bar); auto fooAddressInt = find_overload<int, int>(&Foo::bar); Foo foo; (foo.*fooAddressDouble)(0., 0.); (foo.*fooAddressInt)(0, 0); auto globalAddressDouble = find_overload<double, double>(&quux); auto globalAddressInt = find_overload<int, int>(&quux); globalAddressDouble(0., 0.); globalAddressInt(0, 0); }
As you can see, find_overload accepts both free functions and member functions (for which it infers the class type as well as the return type).
source share