First pointer to member functions != pointer to free functions
Quote:Original post by JohnHurt
// base class for all GUI objectsclass gtGuiWidget{protected: // callback function pointer////////// void (*gtGuiWidget::fpLButtonDownCallback)(void);//...
This is incorrect syntax for pointer to member functions:
struct widget { // typedef introduces a type alias for another type // use it to make code clear and concise typedef void (widget::*button_handler)(); //....private: button_handler b_hdler; //....};
Quote:Original post by JohnHurt
That works now, although I had to change it to
(*widget->fpLButtonDownCallback)();
This is incorrect aswell but i'm not surprised as you didn't declare a pointer to a member function in the first place.
The correct syntax is:
pointers : (ptr->*mem_func_ptr)();references : (ref.*mem_func_ptr)();
Quote:Original post by JohnHurt
is there a way to pass a function pointer as an argument without having to declare all its own arguments, i.e.:
void SetCallBack(void (*func)(void));
The reason is that I want to be able to pass different function pointers to the same function in my widget class, so that I can set up message maps. For example. Don't nock the simple methods.
widget->SetCallBack(on_l_button_down, L_BUTTON_DOWN);
widget->SetCallBack(on_r_button_down, R_BUTTON_DOWN);
widget->SetCallBack(on_double_click, DOUBLE_CLICK);
etc...
"void (*func)(void)" declares a pointer to function which is not interchangeable with pointer to member functions, they are not equal.
You cannot declare a pointer to free/member function with-out declaring specific arguments, its the signature.
There are many ways to get round that, some of which are:
A. Probably the simplest method is to just have seperate set member function e.g. "setOnButtonDown", setDoubleClick", etc you can always add extra options to each of these. Don't knock simplicity & conciseness.
B. Your method but you have to disregard static typing. This is done by dis-regarding type altogether using the most general pointer type the void pointer (the lowest common dominator of the bunch) and using run-time type switching code or have map that maps key ids to something, when you make a match then you will have to cast the void pointer to the appropriate type. something like so:
enum cb_type { L_BUTTON_DOWN, R_BUTTON_DOWN, DOUBLE_CLICK };void gtGuiWidget::SetCallBack(void* func, cb_type type) { switch(type) { case cb_type::L_BUTTON_DOWN: // ... break; case cb_type::R_BUTTON_DOWN: // ... break; case cb_type::DOUBLE_CLICK: // ... break; default: // .... }}
You are warned this is horrible coding practice (however using a map would improve things only slightly though) because type switching can be a maintenance nightmare, using void pointers is not type safe, you have no compiler support and whole heap of other nasty-ness.
C. Using templates and advance template techniques, tricks, and idioms but (not being rude here) i think this option maybe currently beyond you.
D. I'm probably missing a whole lot of other options but i'm tired and its getting very late now, i'm sure some one else will add some others.
[Edited by - snk_kid on June 4, 2005 3:04:29 AM]