Ron
Ron

Reputation: 2503

Creating jump table of function pointers in C++

I'm trying to create an array of function pointers in C++ that I can use as a jump table. The functions are all prototyped like

void(unsigned char*, int, int)

So I thought I would do

typedef void (*func)(unsighed char*, int, int);

and then

func tfunc[256];

And then set the individual elements like this:

tfunc[0]=func01;

But then I get "function call missing argument list; use '&myclass::func01'"

But then when I try

tfunc[0]=&myclass::func0;

I get "error C2440: '=' : cannot convert from 'void (__thiscall myclass::* )(unsigned char *,int,int)' to 'myclass::tfunc' 1> There is no context in which this conversion is possible

I am confused.

I think I fixed it by adding MyClass:: in the header: tyepdef void (MyClass::*func...);

Upvotes: 1

Views: 3009

Answers (3)

Michael Simbirsky
Michael Simbirsky

Reputation: 3103

If you want to put a class member function into your array, the class member function should be declared static.

In case your class member function is not static, than you have to "bind" this to it, and it forces you to use the solution suggested by @Dietmar.

Upvotes: 0

Thomas Matthews
Thomas Matthews

Reputation: 57718

Even though you have an array of pointers to {static} functions or pointers to members, you will still need to pass the parameters when you call the function:

(*vector_of_functions[i])(param1, param2, param3);

The above is for standalone functions. Executing a member via pointer to member method is left as an exercise to the reader (hint: See C++ faq pointer to member).

Upvotes: 0

Dietmar Kühl
Dietmar Kühl

Reputation: 153840

You could use std::function<void(unsigned char*, int, int)> for your array of functions and appropriately bind your object using std::bind():

using namespace std::placeholders;
std::function<void(unsigned char*, int, int)> tfunc[256];
tfunc[0] = std::bind(&myclass::func0, this, _1, _2, _3);

Using std::function<Signature> is nicer than using function pointers in all cases because it allows to pass through necessary context, e.g., a pointer to an object. If you really mean to just call the function and you don't need an object, you can still use std::function<...> and you made your func0 member static instead. In that case you could still use std::bind() but it isn't really needed:

struct myclass {
    static void func0(unsigned char*, int, int);
};
// ...
tfunc[0] = std::bind(&myclass::func0, _1, _2, _3);
tfunc[0] = &myclass::func0;

For the fans of dynamic polymorphism: internally std::function<...> has an inheritance hierarchy and any concrete initialization instantiates a derived class as needed. The only real differences are that you don't need to faff about creating a hierarchy and some implementations do clever things to make it more efficient.

Upvotes: 1

Related Questions