Viller
Viller

Reputation: 540

Initialization array of pointers to functions

Intro: I'm coding in VS2010 basic calculator based on FSM patter. So, I need action map.

How correctly initialize a static two dimensional array of pointers to functions in C++? I've already tried

static void (*action_map[])() = {A, pA}; //one dimension for example

or

static void (*action_map[])() = {&A, &pA};

and many others doesn't work.

ADDED

Everything should be done inside class. Example below doesn't work for me

public class A {
public:
    void func1() { cout << "func1\n"; }
    void func2() { cout << "func2\n"; }
    void func3() { cout << "func3\n"; }
    void func4() { cout << "func4\n"; }
    typedef void (*function_t)();
    function_t function_array[2][2];
    A();

};

A::A() 
{
    function_array[2][2] = { { func1, func2}, { func3, func4 } };
};

int main(array<System::String ^> ^args)
{
    A * tst = new A();
    for (int i = 0; i < 2; i++)
        {
    for (int j = 0; j < 2; j++)
        {
        tst->function_array[i][j]();
        }
    }
    return 0;
}

Please point what exactly I did wrong.

Upvotes: 1

Views: 3602

Answers (4)

hmjd
hmjd

Reputation: 121971

Note the type 'function_t' has changed:

class A
{
public:
    void func1() { cout << "func1()\n"; }
    void func2() { cout << "func2()\n"; }
    void func3() { cout << "func3()\n"; }
    void func4() { cout << "func4()\n"; }
    typedef void (A::*function_t)();
    static const function_t function_array[2][2];
};

const A::function_t A::function_array[2][2] = { { &A::func1, &A::func2 },
                                                { &A::func3, &A::func4 }
                                              };

// Example use.
A my_a;
for (int i = 0; i < 2; i++)
{
    for (int j = 0; j < 2; j++)
    {
        std::mem_fn(A::function_array[i][j])(my_a);
    }
} 

If the array 'function_array' is changeable between class instances then a 'static const' is not appropriate and it must be populated in the constructor.

Upvotes: 1

Mike Seymour
Mike Seymour

Reputation: 254471

If your compiler supports C++11 initialiser lists, then you just need do drop the spurious array sizes in your assignment.

A::A() 
{
    function_array = { { func1, func2}, { func3, func4 } };
}

Or better still, initialise it directly, rather than assigning after default-initialisation:

A::A() : function_array { { func1, func2}, { func3, func4 } }
{}

If your compiler doesn't support C++11, you'll need to assign them by hand:

A::A()
{
    function_array[0][0] = func1;
    function_array[0][1] = func2;
    function_array[1][0] = func3;
    function_array[1][1] = func4;
}

You'll also need to make the functions static in order to store simple function pointers to them; if they have to be non-static members, then you'll need to either store member-function pointers and call them with a class instance, or store std::function objects, created using std::bind (or their Boost equivalents if you don't have C++11).

Upvotes: 1

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361482

Since you're using MSVS2010 which has implemented many C++11 features, how about doing this:

void f1() {}
void f2() {}
void f3() {}
void f4() {}

std::vector<std::function<void()>> action_map = {f1, f2, f3, f4};

for(size_t i = 0 ; i < action_map.size(); ++i)
{
     action_map[i](); //invoke action!
}

Upvotes: 0

cpx
cpx

Reputation: 17567

Both of them are fine if A and pA are the name of functions taking no arguments and returning a void type.

Upvotes: 0

Related Questions