Add411
Add411

Reputation: 3

Cannot bind function from abstract class in c++

I'm try to use std::bind with a virtual pure function in a abstract class but I use a design pattern call strategy, because I want make a program that can handle dynamic switch between the game.

I don't get the syntax. here is the code :

Here is my interface class

class IGame
{
  public:
    virtual ~IGame(){};
    virtual void move_up(INFO &info)=0;
}

By the way INFO is a define :

 #define INFO std::pair<struct GetMap*, struct WhereAmI*>

Here is my control class in it's constructor I call std::bind call;

 class CGame
  {
  private:
    IGame                                       *game;
    int                                         score;
    std::pair<struct GetMap*, struct WhereAmI*> info; // game information

    std::vector<std::function<void(std::pair<struct GetMap*, struct WhereAmI*>&)>> ptr_move_ft; //function pointer vector

  public:
    CGame();
    ~CGame();
    void return_get_map(INFO &info);
  }

This is the constructor of CGame class :

CGame::CGame()
 {
   game = new Snake();
   this->info = std::make_pair(init_map(MAP_PATH_SNAKE,0), game->init_player());

   ptr_move_ft.push_back(std::bind(&CGame::return_where_i_am, this,std::placeholders::_1)); //this work

   ptr_move_ft.push_back(std::bind(&game->move_up, game, std::placeholders::_1)); //this create a error
 }

So the second push_back makes this error :

source/CGame.cpp: In constructor ‘arcade::CGame::CGame()’:
source/CGame.cpp:131:44: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say ‘&arcade::IGame::move_up’ [-fpermissive]
     ptr_move_ft.push_back(std::bind(&game->move_up, game, std::placeholders::_1));

How can I do ?

Sorry for my poor English and c++ code.

Upvotes: 0

Views: 689

Answers (1)

cdhowie
cdhowie

Reputation: 168988

The problem is the expression &game->move_up in this line:

ptr_move_ft.push_back(std::bind(&game->move_up, game, std::placeholders::_1));

This expression is trying to create a pointer-to-member-function, but these pointers are not bound to a particular instance. Creating a pointer-to-member-function from a particular instance therefore makes no sense, similar to trying to invoke a static method through an instance.

Instead of &game->move_up you should use &IGame::move_up.

You can also use &std::decay<decltype(*game)>::type::move_up. The advantage is that this expression will adjust to match the type of *game, looking for an instance method named move_up on whatever the pointed-to type is. The disadvantage is that the syntax is a bit obtuse.

(Here is a demo that shows how both approaches will yield an identical pointer-to-member-function.)

Upvotes: 1

Related Questions