无法调用结构

时间:2018-08-17 17:07:57

标签: c++ c++11 x11 xlib

我一直在绞尽脑汁,在程序中正确声明,定义并最终调用成员函数指针。

我正在使用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++ 可以编译错误的代码行。

我在做什么错?有没有更好的方法来处理用户键绑定定义?谢谢!

3 个答案:

答案 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}}实例。