将成对的参数包解包成一个数组和一个元组

问题描述

所以我有一个对的列表,其中第一个成员是一个常量整数,第二个是一个类型,无论如何将它解包到第一个成员的数组和第二个成员的元组中?

struct MA {}
struct MB {}
struct MC {}
template <int I,class T> struct MyPair{};

如何制作模板元函数使其具有这两个成员:

MyStruct<1,MA,2,MB,3,MC> {
     std::array<int,3> arr = {1,3};
     using Tuple = std::tuple<MA,MC>;
};

解决方法

只需定义两个辅助元函数即可获得 IT

template<class> struct GetFirst;
template<int I,class T> struct GetFirst<MyPair<I,T>> {
    static constexpr int value = I;
};

template<class> struct GetSecond;
template<int I,class T> struct GetSecond<MyPair<I,T>> {
    using type = T;
};

template<class... MyPairs>
struct MyStruct {
    std::array<int,sizeof...(MyPairs)> arr{GetFirst<MyPairs>::value...};
    using Tuple = std::tuple<typename GetSecond<MyPairs>::type...>;
};

//////////////////////////////////////////////////

using S = MyStruct<MyPair<1,MA>,MyPair<2,MB>,MyPair<3,MC>>;
static_assert(std::is_same_v<S::Tuple,std::tuple<MA,MB,MC>>);
assert((S{}.arr == std::array{1,2,3}));

不能在可变参数模板中混合类型和非类型参数,因此不可能有

MyStruct<1,MA,3,MC,...>

无需将 (int,Type) 包装成类型。


正如 JeJo 在下面的评论中提到的,两个元功能可以合并为一个:

template<class> struct MyPairTraits;
template<int I,class T> struct MyPairTraits<MyPair<I,T>> {
    static constexpr int i = I;
    using Type = T;
};