Вызов функции, зависящей от перечисления

Вот упрощенная настройка моего приложения:

class Engine {
    void run(); { // main program loop
        while (state != gameState::quit)
            step<state>(); // ERROR
    }

    template<gameState>
    void step() {} // empty default step function

    template<>
    void step<gameState::intro>() { /* do step for intro state*/ }
    template<>
    void step<gameState::menu>() { /* do step for menu state*/ }

    gameState state;
}

То, что я хочу сделать, это вызвать функцию шага, зависящую от текущего значения в состоянии члена. В вызове step() состояние не является константным выражением, что является проблемой. Есть ли способ написать этот вызов функции, зависящей от enum, без какого-либо большого уродливого переключателя?

(Это только упрощенный пример с одной функцией и только двумя состояниями).

1 ответ

Решение

Нет, вы не можете избежать использования switch при использовании состояния, которое не constexpr, Это природа конечных автоматов. Все, что вы можете сделать, это попытаться сделать его менее уродливым:

void dispatch_state(gameState st) {
    switch(st) {
        case gameState::intro: handle_intro(); break;
        case gameState::menu:  handle_menu(); break;
        // etc...
    }
}

UPD: существуют другие методы отправки, например, сохранение массива указателей на функции, как предложено @KonstantinL, или наличие std::map из std::functions, но каждый из них требует, чтобы вы вручную записали таблицу с перечислителями и соответствующими обработчиками. Из всех я предпочитаю тот, с минимальной косвенностью, который является простым старым switch,

Другие вопросы по тегам