Развернуть кортеж TYPE в шаблон variadi c? - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть функция main_func, где я изменяю шаблон paramater pack / variadi c, преобразовывая его в кортеж. После того, как я изменил его, например: original = tuple<int, float, string> становится modified = tuple<int float> Я хочу расширить измененный кортеж на другую функцию в примере get_type_vector, чтобы пакет параметров представлял типы измененного кортежа Args = int, float.

template<typename... Args>
void main_func()
{
    // Modify the parameter pack (which if im correct can only be done by converting to tuple?)
    using original = std::tuple<Args...>;
    using modified = // something that alters the types of the original tuple

    // This is what i want to accomplish
    // somehow expand the tuple type like a parameter pack
    auto vec = get_type_vector<modified...>()
}

// Returns a vector of type_info
template<typename... Args>
std::vector<type_info> get_type_vector()
{
    return { type_info<Args>()... };
}

Можно ли как-то расширить тип кортежа, например, тип пакета параметров? Я нашел примеры, используя std::apply et c. но для этого требуется, чтобы у вас было значение, а не только определение типа кортежа.

Ответы [ 2 ]

2 голосов
/ 11 февраля 2020

Вы можете легко расширить кортеж, введя слой косвенности, который может быть лямбда-выражением (C ++ 20) или функцией шаблона (C ++ 11). Например,

std::tuple<int, float, char> t;
[]<typename... Ts>(std::tuple<Ts...>)
{
    // use `Ts...` here
}(t);

В вашем случае:

template <typename T>
struct type_wrapper { using type = T; };

template<typename... Args>
std::vector<type_info> get_type_vector(type_wrapper<std::tuple<Args...>>)
{
    return { type_info<Args>()... };
}

get_type_vector(type_wrapper<std::tuple<int, float, char>>{});

Класс type_wrapper предотвращает ненужные экземпляры кортежей во время выполнения. Вы можете использовать std::type_identity в C ++ 20.

1 голос
/ 11 февраля 2020

Довольно простым подходом было бы просто перегрузить и позволить компилятору определять типы. std::type_identity может быть полезно здесь (C ++ 20, но легко воспроизводится в любой версии C ++). Он может создавать простые дешевые теги из типов

template<typename... Args>
std::vector<type_info> get_type_vector(std::type_identity<std::tuple<Args...>>)
{
    return { type_info<Args>()... };
}

Чтобы использовать это, чтобы написать

auto vec = get_type_vector(std::type_identity<modified>{})
...