Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass a member function pointer into a function that takes a regular function pointer?

I have a player class which looks like this (stripped down to what is needed for this problem):

class Player
{
    public:
        Player();
        ~Player();

        void kill();
        void death();
        void reset();
};

The kill(), death(), and reset() functions look like this:

void Player::kill()
{
    void (*dPtr)() = &death;

    Game::idle(dPtr, 48);
}

void Player::death()
{
    reset();
}

void Player::reset()
{
    //resets
}

The idle function is a static memeber function of Game, which takes a function pointer and an integer n, and calls the function after n tick. Here is the function, the implementation shouldn't matter:

class Game {
    static void idle(void (*)(), int);
};

This code gives me the error:

ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.  Say '&Player::death' [-fpermissive]

So I change the line from

    void (*dPtr)() = &death;

to

    void (Player::*dPtr)() = &Player::death;

to solve that issue. But then my call to the idle function is incorrect, as it takes a regular function pointer, and I am passing in a member function pointer, and thus gives me the error:

no matching function for call to 'Game::idle(void (Player::*&)(), int)'

So my question is: How can I pass the member function pointer Player::*dPtr into the idle function, which takes a void (*)() as an argument?

Or is there another way I can solve my previous error which forbids me from taking the address of an unqualified member function to form a pointer to a member function?

like image 248
Yaxlat Avatar asked Sep 18 '25 00:09

Yaxlat


1 Answers

Another answer mentions that you need two pointers. However C++ already comes with containers for doing just this, so it would make your code a lot simpler to use those. (In C++03, some of the std:: items below were std::tr1::).

Sample code:

#include <iostream>
#include <functional>

struct Game 
{ 
    static void idle( std::function<void()> func, int x )
        { std::cout << "x = " << x << "\n"; func(); }
};

struct Player
{
     void death() { std::cout << "player.death\n"; }
     void kill() { Game::idle( std::bind(&Player::death, this), 48 ); }
};

int main()
{
    Player p;
    p.kill();
}

Lifetime note: std::bind binds by value. Using *this means a copy of the Player is made and stored in the std::function object, copied around with it as necessary.

Using this means the function object stores a pointer, so if you actually store the function object in Game::idle you must take care that this Player is not destroyed before removing this function object from Game::idle's list.

like image 108
M.M Avatar answered Sep 19 '25 14:09

M.M