C++ member function overloading with & (ampersand)

。_饼干妹妹 提交于 2020-01-01 23:10:54

问题


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
}

回答1:


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);



回答2:


You can just explicitly specify the member function pointer type.

int (test::*f1)() = &test::error;
void (test::*f2)(int) = &test::error;



回答3:


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.




回答4:


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);



回答5:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!