Unable to call member function pointer that is inside a struct

点点圈 提交于 2019-12-24 07:37:12

问题


I've been racking my brain over getting the syntax right on declaring, defining and finally calling a member function pointer inside my program.

I'm writing a window manager with Xlib, and am trying to enable the user to define all key bindings in a vector of Keybinds. The Keybind struct contains more member variables, which I have left out here for the sake of brevity.

Here's what I've got so far.

Keybind, a struct containing a member variable, func, that points to a MyClass member function.

struct MyBind {
    MyBind(void (MyClass::*_func)(const XKeyEvent&))
    : func(_func) {}

    void (MyClass::*func)(const XKeyEvent&);
}

Declaration and populating of a vector that holds user-defined Keybinds.

// 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 ));

At this point, everything compiles and runs.

Now, when I try to delegate work by iterating over the my_binds_ vector, things go wrong. It is worth noting that I've left out error handling and other member variable accesses for clarity.

void
MyClass::handle_input(const XKeyEvent& e)
{
    for (const MyBind* my_bind: my_binds_) {
        (my_bind->*func)(e); // erroneous line
    }
}

This should be the correct syntax, but it fails to compile, stating error: ‘func’ was not declared in this scope (g++, similar error from clang++).

This is weird to me, as replacing the erroneous line of code with auto test = keybind->func; does compile.

What am I doing wrong? Is there a better way to handle user key bind definitions? Thanks!


回答1:


It would be best to use std::function and forget about raw member-function pointers altogether. They will only bring you pain :)

The problem with you code is that you only have a pointer to a method but no object. Your bind struct should also store an object pointer to call the method on:

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);
    }
}

And then use it like this:

void
MyClass::handle_input(const XKeyEvent& e)
{
    for (const MyBind* my_bind: my_binds_) {
        (*my_bind)();
    }
}

I've added a call operator to the bind struct for convenience. Note that the ->* operator is applied to the object the method belongs to.




回答2:


This is not an answer, rather a pointer to your answer or my so-question :)

You had to use

(this->*(my_bind->func))(e); 

instead of:

(my_bind->*func)(e); 

I have re-created your error msg and asked a question after many different attempts.

See this( pointer to your answer ;) ): How to call pointer to member function, which has been saved in a vector of custom struct?

MyBind holds the pointer to member function of some instance of MyClass. Therefore in order to call these function pointers, you need to explicitly tell using this keyword, for which instance of MyClass you want the func to be called.



来源:https://stackoverflow.com/questions/51900083/unable-to-call-member-function-pointer-that-is-inside-a-struct

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!