I am trying to use a template class as a work around for callback. I want to use a non-static member function for callbacks.
I created two classes:
//First Class
class AbstractAction
{
public:
AbstractAction() = default;
virtual ~AbstractAction() = 0;
virtual void exec() = 0;
};
//Second class
template<class T>
class Action: public AbstractAction
{
public:
Action<T>(T* obj, void (T::*func)())
: class_obj_(obj), class_func_(func) {}
virtual void exec() {class_obj_->*class_func_;}
private:
T * class_obj_;
void (T::*class_func_)();
};
In my Code I have a class called "Button". This class has a member of AbstractAction. When the Button is pressed it calls the exec() function. exec() is virtual so actually the function of Action<SomeClass> is called.
Now I create a class using an Object of Action
class HardWork
{
public:
HardWork()
: action(this, &HardWork::workOnAction) {}
private:
void workOnAction() { /* do something using non static variables */ };
Action<HardWork> action;
};
And the compile says:
In instantiation of 'void display::Action<T>::exec() [with T = HardWork]':
error: invalid use of non-static member function of type 'void (HardWork::)()'
virtual void exec() {class_obj_->*class_func_;}
^~~~~~~~~~
Why does he complain about this? He has a pointer to an actual object of Hardwork so he should know what to call. Second and more important what way around do I have. I don't want to use the static work around. What options do I have?
When you do
class_obj_->*class_func_;
you dereference the function pointer but you don't actually do anything with it. You still need to call the fuction like you normally would. You do need to add some extra parentheses to do this though and that would look like
virtual void exec() { (class_obj_->*class_func_)();}
^^^^^get function^^^^^^^^^ ^
| call function
To avoid messy syntax of calling through a member function pointer, std::invoke can be used since C++17:
virtual void exec() {
std::invoke(class_func_, class_obj_);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With