是否可以将“integral_constant”列表转换回“T”列表?

Is it possible to convert a list of `integral_constant`s back to a list of `T`'s?

我设法将 template<int ...Args> struct List 转换为 integral_constant 的列表,但是,是否可以从 integral_constant 转换回 int

以下是我如何将 IntList 转换为 List

template<typename ...Args>
struct List;

template<typename T>
struct ListFromTupleImpl;
template<typename ...Args>
struct ListFromTupleImpl<std::tuple<Args...>>
{ using type = List<Args...>; };

template<typename T>
using ListFromTuple = typename ListFromTupleImpl<T>::type;
template<typename ...Args>
using TupleCat = decltype(std::tuple_cat(std::declval<Args>()...));
template<typename ...Args>
using ListFromTupleCat = ListFromTuple<TupleCat<Args...>>;

template<int ...Args>
struct IntList;

template<typename ...Args>
struct List
{
    template<typename T>
    struct Concat;
    template<typename ...Args0>
    struct Concat<List<Args0...>>
    {
        using type = ListFromTupleCat<std::tuple<Args...>,
                                      std::tuple<Args0...>>;
    };
};

template<int ...Args>
struct IntList
{
    template<int first, int ...Args0>
    struct ListBuilder
    {
        using type = typename List<std::integral_constant<int, first>>::
                    template Concat<typename ListBuilder<Args0...>::type>::type;
    };
    template<int last>
    struct ListBuilder<last>
    {
        using type = List<std::integral_constant<int, last>>;
    };
    using asList = typename ListBuilder<Args...>::type;
};

您可以通过让编译器匹配模板模式来做您想做的事情:

template<typename... Ts>
auto to_int_list_helper(List<Ts...>) {
    return IntList<Ts::value...>{};
}

template<typename ListParam>
using AsIntList = decltype(to_int_list_helper(ListParam{}));

和概念证明:

using L = typename IntList<1,2>::asList;

static_assert(is_same<L, List<integral_constant<int, 1>, integral_constant<int, 2>>>::value, "");

using BackToIntList = AsIntList<L>;

static_assert(is_same<IntList<1,2>, BackToIntList>::value, "");

live demo

由于您还询问了串联,因此利用相同的技术非常简单:

template<int... Ts, int... Us>
auto concat_int_lists_helper(IntList<Ts...>, IntList<Us...>) {
    return IntList<Ts..., Us...>{};
}

template<typename A, typename B>
using ConcatIntLists = decltype(concat_int_lists_helper(A{}, B{}));

live demo