Map int to Template int

Viewed 64

Is there a more elegant solution (to a hopefully obvious problem) than

switch(variableInt)
{
    case 0: tmpl<0>::foo(); break;
    case 1: tmpl<1>::foo(); break;
    // up to, say, 10
}

Clearly, this can only be defined in some range. I only found old topics around this, maybe some nice C++17 or C++20 feature that helps us out here?

1 Answers

What about something like this?

#include <utility>

template <std::size_t I>
int foo(int arg) {
    return I * arg;
}

template<std::size_t ...Is>
auto get_foo(std::index_sequence<Is...>, int i) {
    return *(std::initializer_list<int(*)(int)>{&foo<Is>...}.begin() + i);
}

int foo(std::size_t i, int arg) {
    return get_foo(std::make_index_sequence<11>(), i)(arg);
}

Here's another solution that optimizes more nicely:

#include <utility>

template <std::size_t I>
int foo(int arg) {
    return I * arg;
}

template<std::size_t ...Is>
auto foo(std::index_sequence<Is...>, int i, int arg) {
    int ret;
    ((Is == i && (ret = foo<Is>(arg))), ...);
    return ret;
}

int foo(std::size_t i, int arg) {
    return foo(std::make_index_sequence<11>(), i, arg);
}
Related