Как восстановить аргумент шаблона не-typename из каждого типа в вариационной пачке шаблонных классов? - PullRequest
1 голос
/ 10 апреля 2019

Я пытаюсь восстановить аргумент шаблона нетипового имени из пакета переменных классов (где каждый класс имеет один аргумент нетипового типа), чтобы я мог использовать их как целочисленную последовательность в другом типе.

Код ниже показывает, что у меня есть. Целочисленная последовательность / последовательность членов извлекается из кортежа.

template<std::size_t... Integers>
struct size_t_sequence {
    using type = size_t_sequence<Integers...>;
};

template <std::size_t, typename>
struct push_size_t_sequence;

template <std::size_t I, std::size_t... Integers>
struct push_size_t_sequence<I, size_t_sequence<Integers...>>
    : size_t_sequence<I, Integers...> {};

template <std::size_t N, std::size_t Head, std::size_t... Tail>
struct make_size_t_sequence
    : push_size_t_sequence<Head, typename make_size_t_sequence<N - 1, Tail...>::type>::type {};

template<std::size_t I, std::size_t... OneLeft>
struct make_size_t_sequence <2, I, OneLeft...> :
    push_size_t_sequence<I, size_t_sequence<OneLeft...>>::type {};



template<typename... Members>
struct member_sequence {
    using type = member_sequence<Members...>;
};
template <typename, typename>
struct push_member_sequence;

template <typename M, typename... Members>
struct push_member_sequence<M, member_sequence<Members...>>
    : member_sequence<M, Members...> {};

template <std::size_t N, typename Head, typename... Tail>
struct make_member_sequence
    : push_member_sequence<Head, typename make_member_sequence<N - 1, Tail...>::type>::type {};

template<typename M, typename... OneLeft>
struct make_member_sequence <2, M, OneLeft...> :
    push_member_sequence<M, member_sequence<OneLeft...>>::type {};


template<typename>
struct unpack_sequence_impl;

template<template<std::size_t> class... T, std::size_t... DimensionSizes>
struct unpack_sequence_impl<member_sequence<T<DimensionSizes>...>> {
    using member_types = member_sequence<T<DimensionSizes>...>;
    using size_types = size_t_sequence<DimensionSizes...>;
};

template<typename... Members>
struct unpack_sequence : 
    unpack_sequence_impl<make_member_sequence<sizeof...(Members), Members...>> {
    using base_t = unpack_sequence_impl<make_member_sequence<sizeof...(Members), Members...>>;
    using member_types = typename base_t::member_types;
    using size_types = typename base_t::size_types;
};


template<std::size_t N>
class example {
    int s = N;
};

int main()
{
    auto mem_sequence = make_member_sequence<3, example<3>, example<2>, example<1>>::type();
    auto integer_sequence = make_size_t_sequence<3, 3,2,1>::type();
    auto un_mem_sequence = unpack_sequence<example<3>, example<2>, example<1>>::member_types();
    auto un_size_sequence = unpack_sequence<example<3>, example<2>, example<1>>::size_types();
}

Типы mem_sequence и integer_sequence: member_sequence<example<3>,example<2>,example<1>> и size_t_sequence<3,2,1>. Типы un_mem_sequence и un_size_sequence должны быть одинаковыми.

Как мне это сделать?

Спасибо за помощь!

Тим

Edit:

Для пояснения я пытаюсь восстановить аргументы шаблона из одного класса шаблона, чтобы использовать их в другом. Ниже приведены три класса шаблонов: MyObject, MyTuple, MyPack. MyTuple принимает MyObject объектов в качестве параметров шаблона. Я хочу восстановить параметры шаблона MyObject для использования в качестве аргумента шаблона для объекта MyPack.

template<int N>
MyObject;

template<int... Ns>
MyPack;

template<typename... MyObjects>
MyTuple {};



int main() {
    MyTuple<MyObject<1>,MyObject<2>,MyObject<3>> a;
    MyPack<1,2,3> b;
}

Итак, я хочу получить аргументы из MyObject в MyTuple, которые будут использоваться для создания MyPack.

Редактировать 2:

Второе уточнение: MyTuple принимает не только MyObject типы, но и любой тип, который имеет один параметр шаблона int.

template<int N>
MyObject;

template<int N>
MyObject2;

template<int... Ns>
MyPack;

template<typename... MyObjects>
MyTuple {};



int main() {
    MyTuple<MyObject<1>,MyObject<2>,MyObject2<1>,MyObject2<2>> a;
    MyPack<1,2,1,2> b;
}

Ответы [ 2 ]

2 голосов
/ 10 апреля 2019
template <typename>
struct MakeMyPack;

template <int... Ns>
struct MakeMyPack<MyTuple<MyObject<Ns>...>>
{
    using type = MyPack<Ns...>;
};

DEMO

0 голосов
/ 11 апреля 2019

Для пояснения я пытаюсь восстановить аргументы шаблона из одного класса шаблона, чтобы использовать их в другом. Ниже представлены три класса шаблонов: MyObject, MyTuple, MyPack. MyTuple принимает объекты MyObject в качестве параметров шаблона. Я хочу восстановить параметры шаблона MyObject для использования в качестве аргумента шаблона для объекта MyPack.

Ради интереса я предлагаю более общее решение с двойным вариационным шаблоном (template-template и value template), не привязанным к MyTuple и MyObject

template <typename>
struct getMyPack;

template <template <typename...> class C,
          template <int> class ... Cs, int ... Is>
struct getMyPack<C<Cs<Is>...>>
 { using type = MyPack<Is...>; };

Ниже приведен полный пример компиляции

#include <type_traits>

template <int>
struct MyObject1
 { };

template <int>
struct MyObject2
 { };

template <int...>
struct MyPack
 { };

template <typename...>
struct MyTuple
 { };

template <typename>
struct getMyPack;

template <template <typename...> class C,
          template <int> class ... Cs, int ... Is>
struct getMyPack<C<Cs<Is>...>>
 { using type = MyPack<Is...>; };


int main ()
 {
   using T0 = MyTuple<MyObject1<1>, MyObject2<2>, MyObject1<3>>;
   using T1 = MyPack<1, 2, 3>;
   using T2 = typename getMyPack<T0>::type;

   static_assert( std::is_same<T1, T2>::value, "!" );
 }

- РЕДАКТИРОВАТЬ -

Второе уточнение: MyTuple принимает не только типы MyObject, но и любой тип, имеющий один параметр шаблона int.

Как я и подозревал.

Мое решение небудо для MyObject, поэтому должно работать.

Предыдущий пример изменен, чтобы показать его.

...