C++使用模板类调用非静态成员函数
Posted
技术标签:
【中文标题】C++使用模板类调用非静态成员函数【英文标题】:C++ Use template class to call non static member function 【发布时间】:2019-11-22 20:57:42 【问题描述】:我正在尝试使用模板类来解决回调。我想为回调使用非静态成员函数。
我创建了两个类:
//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_)();
;
在我的代码中,我有一个名为“Button”的类。这个类有一个AbstractAction
的成员。当按下按钮时,它会调用exec()
函数。 exec()
是虚拟的,所以实际上调用了Action<SomeClass>
的函数。
现在我使用 Action
的对象创建一个类
class HardWork
public:
HardWork()
: action(this, &HardWork::workOnAction)
private:
void workOnAction() /* do something using non static variables */ ;
Action<HardWork> action;
;
并且编译说:
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_;
^~~~~~~~~~
他为什么抱怨这个?他有一个指向Hardwork
的实际对象的指针,所以他应该知道该调用什么。其次,更重要的是我有什么办法。我不想使用静态工作。我有什么选择?
【问题讨论】:
这感觉不像是一个可重现的例子,但我可能是错的。 你忘了实际调用:class_obj_->*class_func_
-> (class_obj_->*class_func_)()
【参考方案1】:
当你这样做时
class_obj_->*class_func_;
你取消引用函数指针,但你实际上并没有对它做任何事情。您仍然需要像往常一样调用该函数。您确实需要添加一些额外的括号来执行此操作,并且看起来像
virtual void exec() (class_obj_->*class_func_)();
^^^^^get function^^^^^^^^^ ^
| call function
【讨论】:
我在网上找到的,没有括号。我在最后用括号试过了,但不是两者都试过。不,它正在工作。非常感谢。【参考方案2】:为了避免通过成员函数指针调用的语法混乱,从C++17开始可以使用std::invoke
:
virtual void exec()
std::invoke(class_func_, class_obj_);
【讨论】:
以上是关于C++使用模板类调用非静态成员函数的主要内容,如果未能解决你的问题,请参考以下文章