How to pick the correct error() member function? Do I need to cast somehow?
using namespace std;
struct test
{
int error();
void error(int x);
int fun();
};
int main() {
auto f1 = &test::error; // how to pick the correct function?
auto f2 = &test::fun; // works
}
Do I need to cast somehow?
Yes, you can use static_cast
.
static_cast may also be used to disambiguate function overloads by performing a function-to-pointer conversion to specific type, as in
std::transform(s.begin(), s.end(), s.begin(), static_cast<int(*)(int)>(std::toupper));
So you can:
auto f1 = static_cast<int(test::*)()>(&test::error);
auto f2 = static_cast<void(test::*)(int)>(&test::error);
You can just explicitly specify the member function pointer type.
int (test::*f1)() = &test::error;
void (test::*f2)(int) = &test::error;
You'll need to use a static_cast
to disambiguate.
&test::error
is not evaluable since the function is overloaded. The fact that you are assigning this to something marked auto
is not immediately relevant.
One fix would be to use static_cast<int(test::*)()>(&test::error)
or static_cast<void(test::*)(int)>(&test::error)
as appropriate.
Then auto
will work since there will be no ambiguity in the type deduction.
Since an answer is already given, I'll present a solution that's easier on the eyes. This situation is perfect for a macro if you don't want to write out the cast every time:
template<class T>
using test_type_t = T test::*;
#define TEST_CAST(T, F) static_cast<test_type_t<T>>(&F)
auto f1 = TEST_CAST(void(int), test::error);
Here is the solution when you don't have the internet to read up the ugly function-pointer-to-member syntax:
auto err1 = [](test& t) { return t.error(); };
auto err2 = [](test& t, int x) { return t.error(x); };
Note that up to now you get closures as types and not function pointers. If you wanted function pointers, which is useful if you want to store different member functions with the same signature in an array, you can cast the closure to a (normal) function pointer via +
(see here).
As far I can see at the moment, with the above you can do conceptually anything you can do with function-to-member-pointers -- except of course calling a routine which exactly requires such a pointer. And it's much nicer.
来源:https://stackoverflow.com/questions/35984788/c-member-function-overloading-with-ampersand