Credo che il massimo che si possa ottenere sia questo:
codice:
struct type_a {};
struct type_b {};
struct type_c {};
struct type_d {};
struct type_e {};


auto number (type_a x) {
    return make_tuple(10, "ss"s);
}

auto number( type_b x) {
    return make_tuple("dd"s, 10);
}

template <class T>
auto wrapper (T a) -> decltype(number(a)) {
    return number(a);
}

int main(int argc, char* argv[]) {

        auto t1 = wrapper(type_a{});
        auto t2 = wrapper(type_b{});

}
dove number è in overload. Ovviamente i tipi di t1 e t2 sono incompatibili tra loro. Se è questo quello che ti serve puoi sfruttare questo esempio, altrimenti quello che vorresti fare con la enum è impossibile.