Извлечение параметра шаблона шаблона и параметра шаблона переменной из шаблона класса

Дан следующий шаблон класса:

template <template <typename... Args> class Container, typename... Args>
struct container_type_holder {};

Я хотел бы извлечь его шаблонный параметр шаблона и его переменный параметр для повторного использования в другом контексте. Пример:

using c1 = container_type_holder<std::map, std::string, int>;
using c2 = container_type_holder<tt_parameter<c1>, vt_parameter<c1>>;

куда tt_parameter<c1> это волшебная уловка для извлечения параметра шаблона из c1 и vt_parameter<c1> чтобы извлечь его параметр шаблона variadic.

Чтобы извлечь параметр шаблона шаблона, я попытался добавить псевдоним внутри container_type_holder, но это не сработало, потому что это не полный тип. Чтобы извлечь параметр шаблона variadic, я попробовал ту же стратегию, но безуспешно.

template <template <typename... Args> class Container, typename... Args>
struct container_type_holder 
{
    using container = Container; // doesnt work
    using args = Args...; // ???
};

Я не знаю, возможно ли это или нет, я новичок в мире шаблонов.

2 ответа

Решение

Вы можете использовать эти псевдонимы, чтобы иметь возможность получать параметры шаблона:

template <template <typename... Args> class Container,
          typename... Args>
struct container_type_holder 
{
    template <typename ... Ts>
    using container = Container<Ts...>;

    constexpr std::size arg_count = sizeof...(Args);

    using args_as_tuple = std::tuple<Args...>;

    template <std::size_t I>
    using get_arg = typename std::tuple_element<I, std::tuple<Args...>::type;

// And possibly helpers, such as

    template <template <typename ...> OtherContainer>
    using template_rebind = container_type_holder<OtherContainer, Args...>;
};

и тогда использование может быть:

using c1 = container_type_holder<std::map, std::string, int>;
using c2 = c1::template_rebind<std::unordered_map>;
using c3 = container_type_holder<std::vector, std::pair<c1::get_arg<0>, c1::get_arg<1>>>;

Я не думаю, что это возможно, что вы спрашиваете, но... вы уверены, что не можете написать container_type_holder просто получая тип

template <typename>
struct container_type_holder;

и развивать свою структуру как частичную специализацию?

template <template <typename... Args> class Container, typename... Args>
struct container_type_holder<Container<Args...>> 
 {
   // ...
 };

Этот способ container_type_holder сама специализация, которая извлекает параметры шаблона-шаблона и список вариантов

Я имею в виду: если вы объявите объект

container_type_holder<std::map<std::string, int>>  obj;

в специализации у вас есть, что Container является std::map и это Args... является std::string, int,

Другие вопросы по тегам