C++使用模板class调用非静态成员函数
C++ Use template class to call non static member function
我正在尝试使用模板 class 作为回调的变通方法。我想使用非静态成员函数进行回调。
我创建了两个 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_)();
};
在我的代码中,我有一个名为 "Button" 的 class。此 class 有 AbstractAction
的成员。按下按钮时,它会调用 exec()
函数。 exec()
是虚拟的,所以实际上调用了 Action<SomeClass>
的函数。
现在我使用 Action
的对象创建了一个 class
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_;
您取消了对函数指针的引用,但实际上并未对它执行任何操作。您仍然需要像往常一样调用函数。您确实需要添加一些额外的括号来执行此操作,看起来像
virtual void exec() { (class_obj_->*class_func_)();}
^^^^^get function^^^^^^^^^ ^
| call function
为避免通过成员函数指针调用的语法混乱,自C++17起可以使用std::invoke
:
virtual void exec() {
std::invoke(class_func_, class_obj_);
}
我正在尝试使用模板 class 作为回调的变通方法。我想使用非静态成员函数进行回调。
我创建了两个 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_)();
};
在我的代码中,我有一个名为 "Button" 的 class。此 class 有 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_;
您取消了对函数指针的引用,但实际上并未对它执行任何操作。您仍然需要像往常一样调用函数。您确实需要添加一些额外的括号来执行此操作,看起来像
virtual void exec() { (class_obj_->*class_func_)();}
^^^^^get function^^^^^^^^^ ^
| call function
为避免通过成员函数指针调用的语法混乱,自C++17起可以使用std::invoke
:
virtual void exec() {
std::invoke(class_func_, class_obj_);
}