>>106982649
Based. 99% of the "people" shouldn't swim in dangerous waters desu to be honest.
#include <iostream>
// This overload is added to the set of overloads if C is
// a class or reference-to-class type and F is a pointer to member function of C
template<class C, class F>
auto test(C c, F f) -> decltype((void)(c.*f)(), void())
{
std::cout << "(1) Class/class reference overload called\n";
}
// This overload is added to the set of overloads if C is a
// pointer-to-class type and F is a pointer to member function of C
template<class C, class F>
auto test(C c, F f) -> decltype((void)((c->*f)()), void())
{
std::cout << "(2) Pointer overload called\n";
}
// This overload is always in the set of overloads: ellipsis
// parameter has the lowest ranking for overload resolution
void test(...)
{
std::cout << "(3) Catch-all overload called\n";
}
int main()
{
struct X { void f() {} };
X x;
X& rx = x;
test(x, &X::f); // (1)
test(rx, &X::f); // (1), creates a copy of x
test(&x, &X::f); // (2)
test(42, 1337); // (3)
}