Массив инициализации указателей на функции - PullRequest
1 голос
/ 14 ноября 2011

Вступление: Я пишу в базовом калькуляторе VS2010 на основе шаблона FSM.Итак, мне нужна карта действий.

Как правильно инициализировать статический двумерный массив указателей на функции в C ++?Я уже пробовал

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

или

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

и многие другие не работают.

ДОБАВЛЕНО

Все должно быть сделано внутри класса.Пример ниже не работает для меня

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

Пожалуйста, укажите, что именно я сделал не так.

Ответы [ 4 ]

1 голос
/ 14 ноября 2011

Если ваш компилятор поддерживает списки инициализаторов C ++ 11, то вам просто нужно отбросить размеры ложных массивов в вашем назначении.

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

Или, что еще лучше, инициализируйте его напрямую, а не присваивайте после инициализации по умолчанию:

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

Если ваш компилятор не поддерживает C ++ 11, вам необходимо назначить их вручную:

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

Вам также понадобится сделать функции static, чтобы хранить простые указатели на них; если они должны быть нестатическими членами, то вам нужно либо хранить указатели на функции-члены и вызывать их с экземпляром класса, либо хранить std::function объекты, созданные с использованием std::bind (или их Boost-эквиваленты, если вы не C ++ 11).

1 голос
/ 14 ноября 2011

Обратите внимание, что тип 'function_t' изменился:

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);
    }
} 

Если массив 'function_array' может изменяться между экземплярами класса, тогда 'static const' не подходит и его необходимо заполнить в конструкторе.

0 голосов
/ 14 ноября 2011

Поскольку вы используете MSVS2010, в котором реализовано множество функций C ++ 11, как насчет этого:

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!
}
0 голосов
/ 14 ноября 2011

Оба они хороши, если A и pA являются именами функций, не имеющих аргументов и возвращающих тип void.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...