是否可以将“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, "");
由于您还询问了串联,因此利用相同的技术非常简单:
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{}));
我设法将 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, "");
由于您还询问了串联,因此利用相同的技术非常简单:
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{}));