我一直在绞尽脑汁,在程序中正确声明,定义并最终调用成员函数指针。
我正在使用Xlib编写窗口管理器,并试图使用户能够在Keybind
s向量中定义所有键绑定。 Keybind
结构包含更多成员变量,为简洁起见,在此省略了它们。
这是我到目前为止所拥有的。
Keybind
,一个包含成员变量func
的结构,它指向一个MyClass
成员函数。
struct MyBind {
MyBind(void (MyClass::*_func)(const XKeyEvent&))
: func(_func) {}
void (MyClass::*func)(const XKeyEvent&);
}
声明并填充包含用户定义的vector
的{{1}}。
Keybind
此时,所有内容都会编译并运行。
现在,当我尝试通过遍历// in my_class.hh
std::vector<MyBind*> my_binds_;
// in my_class.cc, constructor
my_binds_.push_back(new MyBind( &MyClass::do_this ));
my_binds_.push_back(new MyBind( &MyClass::do_that ));
向量来委派工作时,事情出了问题。值得注意的是,为了清楚起见,我省略了错误处理和其他成员变量访问。
my_binds_
此should be the correct syntax,但未能编译,说明为void
MyClass::handle_input(const XKeyEvent& e)
{
for (const MyBind* my_bind: my_binds_) {
(my_bind->*func)(e); // erroneous line
}
}
(error: ‘func’ was not declared in this scope
,与g++
类似的错误)。
这对我来说很奇怪,因为用clang++
可以编译错误的代码行。
我在做什么错?有没有更好的方法来处理用户键绑定定义?谢谢!
答案 0 :(得分:1)
最好使用std::function并完全忘记原始的成员函数指针。他们只会给你带来痛苦:)
代码存在的问题是,您只有一个指向方法的指针,而没有对象。您的绑定结构还应该存储一个对象指针,以在以下位置调用方法:
struct MyBind {
MyBind(MyClass *obj, void (MyClass::*_func)(const XKeyEvent&))
: obj(obj), func(_func) {}
MyClass *obj;
void (MyClass::*func)(const XKeyEvent&);
void operator()(const XKeyEvent& event) const
{
(obj->*func)(event);
}
}
然后像这样使用它:
void
MyClass::handle_input(const XKeyEvent& e)
{
for (const MyBind* my_bind: my_binds_) {
(*my_bind)();
}
}
为方便起见,我在绑定结构中添加了一个调用运算符。请注意,->*
运算符应用于该方法所属的对象。
答案 1 :(得分:0)
为什么不使用标准库。即像这样:
#include <algorithm>
#include <functional>
...
typedef std::function<void(const XKeyEvent&)> key_event_handler;
std::vector< key_event_handler > my_binds_;
....
MyClass::MyClass() {
my_binds_.push_back( std::bind(&MyClass::do_this, this, std::placeholders::_1) );
my_binds_.push_back( std::bind(&MyClass::do_that, this, std::placeholders::_1) );
}
....
void MyClass::handle_input(const XKeyEvent& e)
{
std::for_each(my_binds_.begin(), my_binds_.end(), [e] (key_event_handler& hndlr) {
hndlr( e );
} );
}
您也可以研究boost signals2
答案 2 :(得分:0)
这不是答案,而是指向您的答案或我的问题的指针:)
您必须使用
a0e378cfe28
代替:
(this->*(my_bind->func))(e);
我已经重新创建了您的错误消息,并在多次尝试后问了一个问题。
查看以下内容(指向答案的指针;)):How to call pointer to member function, which has been saved in a vector of custom struct?
(my_bind->*func)(e);
持有指向MyBind
某些实例的成员函数的指针。因此,为了调用这些函数指针,您需要使用MyClass
关键字明确地告诉您要调用this
的{{1}}实例。