1

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.

2
  • 1
    What errors do you get? What's the declaration of A and pA? Commented Nov 14, 2011 at 11:02
  • Works for me. Can you give a complete, compilable example, and show the error messages? Commented Nov 14, 2011 at 11:06

4 Answers 4

1

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).

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

Comments

1

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.

Comments

0

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

Comments

0

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!
}

2 Comments

If you're already in C++11, you could just say for (auto f : action_map) { f(); } :-)
@KerrekSB: Yes. :-) (Microsoft might not have this feature, though)

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.