C ++ перечисляет в шаблонную функцию - PullRequest
0 голосов
/ 30 марта 2020

У меня есть класс enum, и у меня есть очень похожий код, который преобразует enum в шаблонный вызов функции:

auto func1(Type type, ...params)
{
    switch (type)
    {
    case Type::typeA: return func1<Type::typeA>(params);
    case Type::typeB: return func1<Type::typeB>(params);
    case Type::typeC: return func1<Type::typeC>(params);
    ...
    }
}

auto func2(Type type, ...params)
{
    switch (type)
    {
    case Type::typeA: return func2<Type::typeA>(params);
    case Type::typeB: return func2<Type::typeB>(params);
    case Type::typeC: return func2<Type::typeC>(params);
    ...
    }
}

// more such func3, func4, ...

Я могу сгенерировать этот код с помощью макросов #define. Могу ли я что-нибудь сделать с шаблонами? Я могу создать шаблонный класс для каждого типа перечисления, каждый класс содержит все функции. Но как вызвать эту функцию по имени?

Ответы [ 2 ]

1 голос
/ 30 марта 2020

Вы можете сделать что-то вроде:

template <typename Func, typename... Params>
auto visit(Func func, Type type, Params&&... params)
{
    switch (type)
    {
    case Type::typeA:
        return func(std::integral_constant<Type, Type::typeA>{}, std::forward<Params>(params)...);
    case Type::typeB:
        return func(std::integral_constant<Type, Type::typeB>{}, std::forward<Params>(params)...);
    case Type::typeC:
        return func(std::integral_constant<Type, Type::typeC>{}, std::forward<Params>(params)...);
    //...
    }
}

С вызовом, похожим на:

visit([](auto t, int e){ return Func1<t()>(e); }, type, 42);

Демо

0 голосов
/ 30 марта 2020

Вы можете передать func1/2/3 в качестве параметра шаблона шаблона и переадресовать вызов на него.

typename <template <typename> typename Func, typename... Params>
auto switchFunction(Type type, Params&&... params) {
    switch (type)
    {
    case Type::typeA: return Func<Type::typeA>(std::forward<Params>(params)...);
    case Type::typeB: return Func<Type::typeB>(std::forward<Params>(params)...);
    case Type::typeC: return Func<Type::typeC>(std::forward<Params>(params)...);
    ...
    }
}

Затем вы будете использовать это как

auto someOtherFunc(Type type, int param1, double param2)
{
    return switchFunction<func1>(type, param1, param2);
}

Чтобы это работало, все версии func1 должны возвращать один и тот же тип.

Кроме того, все вызовы на func1 должны быть действительными. Не только тот, который выбран переключателем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...