How do I get a method pointer to a particular overload of a method:
struct A {
void f();
void f(int);
void g();
};
I know that
&A::g
is a pointer to g
. But how do I get a pointer to f
or f(int)
?
(void (A::*)()) &A::f
(void (A::*)(int)) &A::f
function pointers and member function pointers have this feature - the overload can be resolved by to what the result was assigned or cast.
If the functions are static, then you should treat them as ordinary functions:
(void (*)()) &A::f;
(void (*)(int)) &A::f;
or even
(void (*)()) A::f;
(void (*)(int)) A::f;
You just have to cast the result of &A::f
in order to remove the ambiguity :
static_cast<void (A::*)()>(&A::f); // pointer to parameterless f
static_cast<void (A::*)(int)>(&A::f); // pointer to f which takes an int
Thanks to Stefan Pabst for the following idea, which he presented in a five minute lightning talk at ACCU 2015. I extended it with tag types to allow for resolving overloads by their cv qualifier and/or reference qualifier, and a C++17 variable template to avoid having to type the extra pair of parentheses which is otherwise required.
This solution works on the same principle as the cast-based answers, but you avoid having to restate either the return type of the function or, in the case of member functions, the name of the class which the function is a member of, as the compiler is able to deduce these things.
bool free_func(int, int) { return 42; }
char free_func(int, float) { return true; }
struct foo {
void mem_func(int) {}
void mem_func(int) const {}
void mem_func(long double) const {}
};
int main() {
auto f1 = underload<int, float>(free_func);
auto f2 = underload<long double>(&foo::mem_func);
auto f3 = underload<cv_none, int>(&foo::mem_func);
auto f4 = underload<cv_const, int>(&foo::mem_func);
}
The code implementing the underload
template is here.