0

I'm trying to make an array of functions so I can call functions from the array with an index. I can't seem to figure out the parentheses, asterisks and brackets to create this array of functions. Here is what I have:

void Game::getPawnMoves(int position, bool color, Move ** moveList) {
    ...
}

typedef void (*GetMoveFunction) (int, bool, Move **);
void Game::getLegalMoves(Move ** moveList) {
    GetMoveFunction functions[] = 
    {
        getPawnMoves, 
        getKnightMoves, 
        getBishopMoves,
        getRookMoves,
        getQueenMoves,
        getKingMoves
    };
    ...
}

All of the getPawnMoves, getKnightMoves, and the rest all have the same arguments and all return void. Move is just a struct with two chars and an enum. In this case, if you'd like to try compiling it, you could replace Move ** with int **.

The error I'm getting when I compile is:

Game.cpp:443:5: error: cannot convert ‘Game::getPawnMoves’ from type 
‘void (Game::)(int, bool, Move**) {aka void (Game::)(int, bool, Move_t**)}’ to 
type ‘GetMoveFunction {aka void (*)(int, bool, Move_t**)}’

So for some reason the compiler thinks that GetMoveFunction is void * instead of void, but if I change the typedef to

typedef void (GetMoveFunction) (int, bool, Move **);

I get the error:

Game.cpp:435:28: error: declaration of ‘functions’ as array of functions
  GetMoveFunction functions[] = 

I'm honestly super stuck on this one. Thanks so much for your help!

8
  • 2
    Regular function pointers can't point to non-static member functions. There are member function pointers that can do that. Commented Feb 28, 2022 at 18:34
  • std::vector<std::function<void(int, bool, Move**)>>? Then use lambdas or std::bind or similar tools to use specific objects. Commented Feb 28, 2022 at 18:35
  • void (*)(int, bool, Move_t**) is the same type GetMoveFunction refers to. You could write (for imho improved readability): using GetMoveFunction = void (*)(int, bool, Move_t**); instead of the typedef and it would mean the exact same thing. The type has nothing to do with void*; the brackets around * change the meaning. Commented Feb 28, 2022 at 18:36
  • The first error, the code you didn't show as part of a proper minimal reproducible example would reveal that Game::getPawnMoves is a non-static member function. Therefore, the actual type of that function is void (Game::*)(int, bool, Move **), not void (*)(int, bool, Move **). The second error is just a side-show of misunderstanding the first error and stabbing at a solution. Commented Feb 28, 2022 at 18:39
  • Member functions, unless declared static are not normal functions because they have an hidden argument this that refers to the instanced object. Commented Feb 28, 2022 at 18:39

1 Answer 1

2

How Should I Define an Array of Pointers to Functions in C++?

typedef void (*GetMoveFunction) (int, bool, Move **);

This is a pointer to function.

GetMoveFunction functions[] = 
{
    // ...
};

This is an array of pointers to functions. You've achieved what you asked for in the title of the question.


Game.cpp:443:5: error: cannot convert ‘Game::getPawnMoves’ from type 
‘void (Game::)(int, bool, Move**) {aka void (Game::)(int, bool, Move_t**)}’ to 
type ‘GetMoveFunction {aka void (*)(int, bool, Move_t**)}’

The problem here is that you are trying to initialise the function pointers using non-static member functions. Function pointers cannot point to non-static member functions.

What you probably need is an array of pointers to member functions of Game instead. Another option is an array of type erasing function wrappers (std::function).

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks so much! I'll edit my question with the updated code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.