Dron
Dron

Reputation: 47

Calling template pointer to member function

Im working on a GUI and i want to be able to pass function pointers to my buttons, however, these could be called from different kinds of classes, which is why i made it use templates.

I do believe it stores the function pointer correctly but i cannot call it correctly.

class MainMenuScene: public Scene
{
    public:
        void add_button(){
            void (MainMenuScene::*func)();
            func = &MainMenuScene::test;
            Button b(func);
            b.click();
        }
        void test();
    private:
        GUI<MainMenuScene> gui;
};


template<class T>
class Button: public GUI_object{
public:
    Button(void (T::*func)());
    void click(){
        func_();
private:
    void (T::*func_)();
};

This is the error i get:

Button.h|23|error: must use '.*' or '->*' to call pointer-to-member function 
in '((Button<MainMenuScene>*)this)->Button<MainMenuScene>::func_ (...)', 
e.g. '(... ->* ((Button<MainMenuScene>*)this)->Button<MainMenuScene>::func_) (...)'|

Upvotes: 1

Views: 4470

Answers (2)

Marius Bancila
Marius Bancila

Reputation: 16338

The function that you store a pointer to is not a static function so you need an object instance to call it.

Something like this maybe:

class MainMenuScene: public Scene
{
    public:
        void add_button(){
            void (MainMenuScene::*func)();
            func = &MainMenuScene::test;
            Button<MainMenuScene> b(this, func);
            b.click();
        }
        void test();
    private:
        GUI<MainMenuScene> gui;
};


template<class T>
class Button: public GUI_object{
public:
    Button(T* obj, void (T::*func)());
    void click(){
        (obj_->*func_)(); }
private:
    void (T::*func_)();
    T* obj_;
};

Upvotes: 3

user955279
user955279

Reputation:

A member function pointer must be used on a specific object. For example, in your case you would need a MainMenuScene object on which to call your function pointer.

Example:

class MainMenuScene
{
public:
    void test() {
        std::cout << "Hello!" << std::endl;   
    }
};


int main()
{

    void (MainMenuScene::*myPointerToMember)() = &MainMenuScene::test;

    MainMenuScene myObj{};
    MainMenuScene* myObjP = &myObj;

    (myObj.*myPointerToMember)();  //Parentheses around (myObj.*myPointerToMember) are important
    (myObjP->*myPointerToMember)(); 
}

Upvotes: 2

Related Questions