Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: a pointer to a bound function may only be used to call the function

I've been trying to assign a function pointer (of a class) to a member function (of another class) like this:

--- Game.h ---
#ifndef GAME_H
#define GAME_H

#include "Screen.h"

class Game
{
private:
    void (*HandleCurrentScreen)();

public:
    void SetScreen(const Screen& newScreen);
};

#endif



--- Game.cpp ---
#include "Game.h"
#include "Screen.h"

void Game::SetScreen(const Screen& newScreen)
{
    HandleCurrentScreen = newScreen.Handle;    //Produces the error
}



--- Screen.h ---
#ifndef SCREEN_H
#define SCREEN_H

class Screen
{
public:
    void Handle();
};

#endif



--- Screen.cpp ---
#include "Screen.h"

void Screen::Handle()
{
    ...
}

I get this error:

error C3867: 'Screen::Handle': function call missing argument list; use '&Screen::Handle' to create a pointer to member

It seems to work fine if HandleCurrentScreen points to a function that is also defined in the Game class. I've been looking for other people with this problem, but none seem to have it in cases like this.

A solution that might work is something like this:

Screen* p_currentScreen;

void Game::SetScreen(const Screen& newScreen)
{
    p_currentScreen = &newScreen;
}

and then instead of calling HandleCurrentScreen I can call p_currentScreen->Handle(), but this seems slightly less efficient to me.

What can I do to fix this? Should I just use a pointer to a class instead of a function pointer?

Any advice is welcome.

like image 797
Hans Avatar asked Dec 06 '25 03:12

Hans


1 Answers

Your error tells you what to do:

Screen::Handle': function call missing argument list; use '&Screen::Handle

You should write it as:

void Game::SetScreen(const Screen& newScreen)
{
    HandleCurrentScreen = &Screen::Handle;
}

It will work only in case newScreen::handle is a static function. But in that case you could initialize it at compile time. Otherwise HandleCurrentScreen should be a pointer to a member function (PTMF) declared as:

void (Screen::*HandleCurrentScreen)();

Now, in order to call the function from a PTMF you need a function object as well. That makes your second solution better.

Another option is std::bind:

class Game
{
private:
    std::function<void()> HandleCurrentScreen;

public:
    void SetScreen(const Screen& newScreen) {
        HandleCurrentScreen = std::bind(&Screen::Handle, &newScreen);
    }
};
like image 173
Adam Kosiorek Avatar answered Dec 08 '25 17:12

Adam Kosiorek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!