2017-04-15 82 views
0

这里被简化我的应用程序的设置:枚举值相关的函数调用

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()调用中,状态不是一个常量表达式,这是一个问题。有没有办法写这个枚举相关的函数调用没有一些大的丑陋的开关?

(这只是一个功能只有2个状态的简单示例)。

+0

您的步骤模板本质上是一个编译时构造,而run()选择本质上是一个运行时构造。你不能混合两者。您可以应用一些元编程来枚举编译时所有可能的状态并生成一些运行时交换机。或者你可以使用其中一个像Boost MSM那样的库。 –

+0

[本文](https://kfrlib.com/blog/how-c14-and-c17-help-to-write-faster-and-better-code-real-world-examples/)提到了一个'cswitch'可以有效地用于这个模板。 – zett42

回答

2

不,你不能避免在使用不是constexpr的状态时使用switch。这是状态机的本质。你所能做的就是尽量让它看起来不那么难看:

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

UPD:还有其他的分配技术,例如存储一个函数指针数组作为@KonstantinL建议,或者有一个的s,但它们中的每一个都需要你用枚举数和相应的处理程序手动写下一个表。在他们之中,我更喜欢那种具有最小间接指标的指标,它是普通的switch

+0

是的,我试着用函数的数组来写它,但在引擎ctor中的数组初始化只要使用开关,但很丑陋 –

+0

好吧,我已经将所有在主程序循环中调用的依赖于状态的函数一个模板化的循环函数,我在你的例子中就像你在开关中所称的那样。感谢帮助。 –