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

14,783

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);
    }
};
Share:
14,783
Hans
Author by

Hans

Updated on June 14, 2022

Comments

  • Hans
    Hans almost 2 years

    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.

  • aruisdante
    aruisdante almost 10 years
    Of course, std::bind only exists in C++11. If you're on an earlier compiler, you'll have to use boost::bind, which is where std::bind got its inspiration.
  • Darrow Hartman
    Darrow Hartman over 2 years
    As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
  • Madhav Balakrishnan Nair
    Madhav Balakrishnan Nair over 2 years
    There is nothing else to do. Do you want a documentary?