0

Let't suppose I have this code:

// the enumerator
enum class my_enum {
    ONE,
    TWO,
    THREE
};

// the function
template <my_enum E>
int foo() {
    return 0;
}

// a specialization
template<>
int foo<my_enum::TWO>() {
    return 1;
}

I would like to write a bar function that specializes foo for each element of my_enum, and that calls, at run-time, one of those functions based on the value of an argument of bar. The simplest solution is to write a switch and manually adding all the cases:

int bar(my_enum value) {
    switch (value) {
    using m = my_enum;
    case m::ONE:
        return foo<m::ONE>();
    case my_enum::TWO:
        return foo<m::TWO>();
    case my_enum::THREE:
        return foo<m::THREE>();
    }
}

with some additional tricks to handle a unexpected value adding a default value of the switch. Unfortunately, for very long enumerators this solution brings to very long and redundant code, that is difficult to be maintained.

Is there any metaprogramming solution to simplify this code, for example using Boost Hana or Boost MPL?

1

1 Answer 1

1

If the enum values are, as in your example, starting from zero and consecutive... given an helper function as follows

template <std::size_t ... Is>
std::array<int(*)(void), sizeof...(Is)>
    getFuncArray (std::index_sequence<Is...>)
 { return {{ &foo<static_cast<my_enum>(Is)>... }}; }

you can add, in bar(), a static array of functions and call the correct one according the input.

I mean

int bar (my_enum value)
 {
   static auto const arrF
      = getFuncArray(std::make_index_sequence<
                        1u+static_cast<std::size_t>(my_enum::THREE)>{});

   return arrF[static_cast<std::size_t>(value)]();
 }
Sign up to request clarification or add additional context in comments.

2 Comments

The logic is fine but, unfortunately, it works only if the enumeration starts from zero and is consecutive :(
@GiovanniCerretani - Unfortunately. You can also use a map, instead of an array, when the enum values are sparse; but I don't know how initialize the map.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.