Michael Doostdar
Michael Doostdar

Reputation: 3

C++, Passing non-static function pointer in a class constructor

I get the following compiler error when I used non-static function pointer in the constructor argument at myclass_2, void load (void) method.

Reference to non-static member function must be called

If I change the function to static void load (void) no error. but I need to have non-static function, I have to work on some global variable in load function. Any help would be appreciate it.

class myclass{
public:
    //_load_event_handler
    vector<Function> _handler_one;
    vector<Function> _handler_two;
    vector<Function> _handler_three;

    void register_for_load_event(void(*fun)(void)){
        this->_handler_three.push_back(fun);
    }

    void register_for_dowork_event(void(*fun)(void)){
        this->_handler_one.push_back(fun);
    }
    void register_for_end_event(void(*fun)(void)){
        this->_handler_two.push_back(fun);
    }
    void run (char **fileNames)
    {
        for (int i = 0; i< _handler_one.size();i++)
            _handler_one[i]();


        for (int i = 0; i< _handler_two.size();i++)
            _handler_two[i]();


        for (int i = 0; i< _handler_three.size();i++)
            _handler_three[i]();
    }


};

class myclass_2
{
public:
    myclass *ptrmyclass;
    void load(void)
    {
        cout << "load function start" << endl;

        //some code here
    }
    myclass_2(myclass *_ptrmyclass)
    {
        ptrmyclass = _ptrmyclass;
        ptrmyclass->register_for_load_event(load);

    }
    void foo(vector<string> vect)
    {
        cout<< "is stop word called" << endl;
    }
};

Upvotes: 0

Views: 363

Answers (2)

John Zwinck
John Zwinck

Reputation: 249293

Make sure Function is std::function<void()>, then change register_for_load_event to take a Function instead of what it takes now. Finally, call it like this:

ptrmyclass->register_for_load_event(std::bind(&myclass_2::load, this));

std::bind() is needed because Function is nullary (takes no arguments), but myclass_2::load() requires one argument: the implicit this (because it is non-static, so requires an instance of myclass_2. "Binding" the member function allows you to provide the this pointer at bind-time, but delay calling the function until later, when no arguments will be required.

Upvotes: 3

Marson Mao
Marson Mao

Reputation: 3035

Is this what you need?

Modifications:

  1. I dont see what Function is in the question so I assume that to be std::function<void()>.
  2. input of register_for_load_event should be a valid function object, so it needs a bind.

using namespace std;
class myclass{
public:
    //_load_event_handler
    typedef std::function<void()> Function; // -------- #1
    vector<Function> _handler_one;
    vector<Function> _handler_two;
    vector<Function> _handler_three;

    void register_for_load_event(Function fun){
        this->_handler_three.push_back(fun);
    }

    void register_for_dowork_event(Function fun){
        this->_handler_one.push_back(fun);
    }
    void register_for_end_event(Function fun){
        this->_handler_two.push_back(fun);
    }
    void run (char **fileNames)
    {
        for (int i = 0; i< _handler_one.size();i++)
            _handler_one[i]();


        for (int i = 0; i< _handler_two.size();i++)
            _handler_two[i]();


        for (int i = 0; i< _handler_three.size();i++)
            _handler_three[i]();
    }


};

class myclass_2
{
public:
    myclass *ptrmyclass;
    void load(void)
    {
        cout << "load function start" << endl;

        //some code here
    }
    myclass_2(myclass *_ptrmyclass)
    {
        ptrmyclass = _ptrmyclass;
        ptrmyclass->register_for_load_event(bind(&myclass_2::load, this)); // -------- #2

    }
    void foo(vector<string> vect)
    {
        cout<< "is stop word called" << endl;
    }
};

Upvotes: 1

Related Questions