I'm trying to create sort of an event system, I don't care if it is suboptimal, I'm doing it for fun. I do not want alternate solutions, I want to understand why this isn't working and how could I fix it.
I'm using this page as reference to do so "https://isocpp.org/wiki/faq/pointers-to-members#fnptr-vs-memfnptr-types"
I want event_triggerer
to store the functions it needs to call from event_receiver
and be able to call them on the stored object
This is the relevant code:
typedef void(event_receiver::* ev_rec_func)(const event_receiver::Msg&);
class event_receiver {
public:
struct Msg {
int irrelevant_test_data;
};
virtual void event_callback0(const Msg& m) {};
};
class event_triggerer {
private:
std::vector<std::pair<event_receiver*, ev_rec_func>> suscribers_vec;
public:
void trigger_event(const event_receiver::Msg& m) {
for (std::pair<event_receiver*, ev_rec_func>& e : suscribers_vec) {
//this line show the error expression must have pointer to member type
e.first->*(e.second(m));
}
}
Visual Studio displays this when I hover over ev_rec_func
:
typedef void ev_rec_func(const &)
But I cannot understand why.
Im not really used to typedef syntax, so I guess there's something wrong with it.
I also found this answer but could not understand whats wrong with mine C++: Calling member function via pointer
I rewrote this line e.first->*(e.second(m));
as "(e.first->*e.second)(m);
but it still generates an error, this time is:
"a pointer to a bound function may only be used to call the function"
How can I solve the error ?
There are several issues in your code:
Your typedef
for ev_rec_func
has to be declared after class event_receiver { ... };
because it refers to event_receiver::...
and so event_receiver
must already be known.
Note: you can consider to replace the typedef
with a more modern type alias (AKA using declaration):
using ev_rec_func = void(event_receiver::*)(const event_receiver::Msg&);
As @DominikKaszewski commented, you have to change the method invoke syntax to:
(e.first->*(e.second))(m);
The reason is that it is a matter of Operator Precedence.