2017-04-15 80 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

好吧,我已經將所有在主程序循環中調用的依賴於狀態的函數一個模板化的循環函數,我在你的例子中就像你在開關中所稱的那樣。感謝幫助。 –