如何从可变参数包模板 类 中的每个类型恢复非类型名模板参数?
How can a recover the non-typename template argument from each type in a variadic pack of template classes?
我正在尝试从模板 classes 的可变包中恢复非类型名模板参数(其中每个 class 都有一个非类型参数),以便我可以将它们用作另一种类型的整数序列。
下面的代码显示了我所拥有的。整数序列/成员序列是从元组中抄袭的。
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
的类型应该是一样的。
我怎样才能做到这一点?
感谢您的帮助!
蒂姆
编辑:
为了澄清,我试图完成的是从一个模板 class 恢复模板参数以在另一个模板中使用它们。以下是三个模板 classes: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;
}
template <typename>
struct MakeMyPack;
template <int... Ns>
struct MakeMyPack<MyTuple<MyObject<Ns>...>>
{
using type = MyPack<Ns...>;
};
For clarification what I am trying to accomplish is recovering the template arguments from one template class to use them in another. Below are three template classes: MyObject, MyTuple, MyPack. MyTuple takes MyObject objects as its template parameters. I want to recover the MyObject template parameters to use as the template argument for a MyPack object.
只是为了好玩,我提出了一个更通用的解决方案,带有双可变参数模板(模板模板和值模板),不受 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, "!" );
}
-- 编辑--
Second clarification: MyTuple does not just take MyObject types but any type that has one template parameter of int.
正如我所怀疑的那样。
我的解决方案不适合 MyObject
,所以应该可行。
修改前面的示例以显示它。
我正在尝试从模板 classes 的可变包中恢复非类型名模板参数(其中每个 class 都有一个非类型参数),以便我可以将它们用作另一种类型的整数序列。
下面的代码显示了我所拥有的。整数序列/成员序列是从元组中抄袭的。
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
的类型应该是一样的。
我怎样才能做到这一点?
感谢您的帮助!
蒂姆
编辑:
为了澄清,我试图完成的是从一个模板 class 恢复模板参数以在另一个模板中使用它们。以下是三个模板 classes: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;
}
template <typename>
struct MakeMyPack;
template <int... Ns>
struct MakeMyPack<MyTuple<MyObject<Ns>...>>
{
using type = MyPack<Ns...>;
};
For clarification what I am trying to accomplish is recovering the template arguments from one template class to use them in another. Below are three template classes: MyObject, MyTuple, MyPack. MyTuple takes MyObject objects as its template parameters. I want to recover the MyObject template parameters to use as the template argument for a MyPack object.
只是为了好玩,我提出了一个更通用的解决方案,带有双可变参数模板(模板模板和值模板),不受 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, "!" );
}
-- 编辑--
Second clarification: MyTuple does not just take MyObject types but any type that has one template parameter of int.
正如我所怀疑的那样。
我的解决方案不适合 MyObject
,所以应该可行。
修改前面的示例以显示它。