建議的地圖或指針處理函數表的答案是好的。但我看到兩個缺點: 1)與手動嵌套開關相比,性能下降較小。 2)案件處理方法不完全自我描述。我的意思是你必須提及每個處理方法兩次 - 在其定義和你創建地圖的地方。
我看到兩個備選方案: 1)源代碼生成。從某種表示自動生成嵌套開關。那麼......如果不介意爲這麼小的任務添加代碼生成,那麼創建最佳代碼是非常好的選擇。 2)使用預處理器黑客。不是最優雅,但相當有趣的方式,使其工作。
首先聲明X-Macro我們的枚舉:
#define ELEMENTS(processor) \
processor(firstElement) \
processor(secondElement) \
processor(thirdElement)
我們可以用它來聲明枚舉本身:
#define ENUM_PROCESSOR(arg) arg,
enum class
{
ELEMENTS(ENUM_PROCESSOR)
};
#undef ENUM_PROCESSOR
Now we can add method that uses macros to generate nested switches:
void processElements(const Elements element1,
const Elements element2)
{
// These macros are useful to trick the preprocessor to allow recursive macro calls
// https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms
#define EMPTY(...)
#define DEFER(...) __VA_ARGS__ EMPTY()
#define EXPAND(...) __VA_ARGS__
#define ELEMENTS_INT() ELEMENTS
#define PROCESS_NESTED_ENUM_VALUE(value) \
case Elements::value: \
{ \
process<Value1, Elements::value>(); \
break; \
}
#define PROCESS_ENUM_VALUE(value) \
case Elements::value: \
{ \
constexpr Elements Value1 = Elements::value; \
switch (element2) \
{ \
DEFER(ELEMENTS_INT)()(PROCESS_NESTED_ENUM_VALUE) \
}; \
\
break; \
}
switch (element1)
{
EXPAND(ELEMENTS(PROCESS_ENUM_VALUE));
};
#undef EMPTY
#undef DEFER
#undef EXPAND
#undef ELEMENT_TYPES_INT
#undef PROCESS_ENUM_VALUE
#undef PROCESS_NESTED_ENUM_VALUE
}
很多拓展力度這裏都是爲了「絕招」預處理器ELEMENTS遞歸。主要想法很好地描述了here。
現在,我們宣佈我們的處理程序爲模板功能專業化:
template <Elements Element1, Elements Element2>
void process();
template<>
void process<Elements::firstElement, Elements::firstElement>()
{
//some code 1;
}
...
這個問題可能會有所幫助。 http://stackoverflow.com/questions/126409/ways-to-eliminate-switch-in-code – RDX 2013-02-12 07:59:43
對於鏈接答案中的多態性+1。 – Najzero 2013-02-12 08:04:45
這些「usecases」,他們是一種狀態?所以你的類是一個狀態機,它在執行期間改變它的狀態('input1') – leemes 2013-02-12 08:15:05