The proposed answers with map or table of pointers to handle functions are ok. But I see two downsides: 1) A small performance decrease comparing to the manual nested switches. 2) Case handling methods aren't fully self-descriptive. I mean you have to mention each handle methods twice - in its' definition and in the place where you init the map.
I see two alternative options: 1) Source code generation. Automatically generate nested switches from some kind of representation. Well... it's very good option to create optimal code, if don't mind adding code generation for such a small task. 2) Using preprocessor hacks. Not the most elegant but quite interest way to make it work.
First we declare X-Macro for our enum:
#define ELEMENTS(processor) \ processor(firstElement) \ processor(secondElement) \ processor(thirdElement)
We can use it to declare the enum itself:
#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 }
A lot of efforts here are made to "trick" preprocessor to expand ELEMENTS recursively. The main idea is well described here.
Now we declare our handlers as template function specialization:
template <Elements Element1, Elements Element2> void process(); template<> void process<Elements::firstElement, Elements::firstElement>() { //some code 1; } ...
input1) during execution?input2? And more specific: Can they overlap? (For a particular value of input2, are there equal implementations among different values of input1?)