Получить зависимый тип пакета параметров шаблона variadi c - PullRequest
0 голосов
/ 23 января 2020

Допустим, у меня есть:

struct M1 { static constexpr int T = 3; }
struct M2 { static constexpr int T = 8; }
struct M3 { static constexpr int T = 19; }

Это действительно два связанных вопроса:

  1. Каков наилучший способ хранения списка всех типов M, таких, что позже Мне не придется повторяться?

в fantasy-c ++: using AllMs = <M1, M2, M3>;

Учитывая этот список, как мне получить список M :: T (но как типы)?

в fantasy-c ++: using AllMTs = AllMs::T ...; (возможно, используя std :: integra_type)


Например, я могу умножить наследование от всех O следующим образом:

template <class... M> class K: public O<M>... { }

template <typename ...P> struct ParameterPackApplicator {
    template <template <typename...> typename T> using apply = T<P...>;
};

using AllM = ParameterPackApplicator<M1, M2, M3>;

using MultiplyInheritedThing = AllM::apply<K>;

... но я не могу понять, как получить список типов всех M :: T ...

Ответы [ 3 ]

1 голос
/ 23 января 2020

Вы не можете создать псевдоним для пакета в C ++. Избыток пакета шаблонов должен выполняться в том же контексте, в котором представлен пакет.

Однако вы можете поместить его в кортеж, а затем распаковать его позже:

using AllMs = std::tuple<M1, M2, M3>;

Затем использовать индексную последовательность чтобы распаковать его:

template<typename = std::make_index_sequence<std::tuple_size_v<AllMTs>>>
struct MyType;

template<std::size_t... S>
struct MyType<std::index_sequence<S...>> : std::tuple_element_t<S, AllMTs>... {};

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

template<typename... AllMs>
struct Inheritance : AllMs... {
    // can do `AllMs::T...` to get all ints
};


struct MyType : Inheritance<M1, M2, M3> {

};
0 голосов
/ 24 января 2020

Так что вы на самом деле не можете делать AllMs :: T ..., как предлагает Гийом. Или, по крайней мере, я не смог получить правильный синтаксис ... ниже работает для меня, хотя.

template <typename... P> struct parameter_pack {
    template <template <typename...> typename T> using apply = T<P...>;
};

template <typename... P>
struct TGetter {
    using Ts = std::integer_sequence<int, P::T...>;
};

using AllTypes = parameter_pack<M1, M2, M3>;

using AllTs = AllTypes::apply<TGetter>::Ts;
0 голосов
/ 23 января 2020

Не уверен, что это именно то, что вам нужно, но вы можете использовать шаблоны c variadi в сочетании с кортежем:

#include <tuple>

struct M1 { int x = 0; };
struct M2 { int y = 0; };

using allM = std::tuple<M1,M2>;

template <typename ... X>
struct foo : public X... {};

template <typename ...X>
struct foo<std::tuple<X...>> : public X... {};

int main() {
    foo<allM> x;
    x.x = x.y;
}
...