我有一个编码为
的类型元组template<class... T>struct packed;
我想稍后将其解压缩,如
template<class T>struct unpack;
template<class... T>
struct unpack<packed<T...>>{
//how to define the unpacked type here?
};
所以,我可以将它用作
template<class Packed>
struct foo : unpack<Packed>::type...{};
注意,我不想像
那样立即解包元组的元素template<class... T>
struct unpack<packed<T...>> : T...{};
template<class Packed>
struct foo: unpack<Packed>{};
我感兴趣的是将元组'packed'的元素作为'foo'的直接基类而不是通过'unack'的间接基类。元组类型的元素也是不同的非原始类型和非最终类型。
为了使示例更加详细,
template<class T, T... Values>
struct variadic_values{};
template<class T,T From,class Encode,T To>
struct value_gen;
template<class T, T From, T... Values, T To>
struct value_gen<T,From,variadic_values<T,Values...>,To>
{
using type = typename value_gen<T,From+1,variadic_values<T,Values...,From>,To>::type;
};
template<class T,T From,T... Values>
struct value_gen<T,From,variadic_values<T,Values...>,From>
{
using type = variadic_values<T,Values...>;
};
template<class T, T From,T To>
using values = typename value_gen<T,From,variadic_values<T>,To>::type;
template<unsigned Idx,class T>
struct node{};
template<class Idx,class... Ts>
struct unpack;
template<unsigned... Idx,class...Ts>
struct unpack<variadic_values<unsigned,Idx...>,Ts...> : node<Idx,Ts>...{};
template<class... Ts>
class foo : unpack<values<unsigned,0,sizeof...(ts)>,Ts...>{};
我感兴趣的是foo
应该直接来自node
s
答案 0 :(得分:2)
你可以这样做:
template <class>
struct foo;
template <class... T>
struct foo<packed<T...>> : T...
{
};
然后您可以将其用作:
typedef packed<A, B, C> packed_type;
typedef foo<packed_type> foo_t; // foo_t derives from A, B, and C
答案 1 :(得分:1)
N.B。这部分问题是不可能的:
template<class Packed>
struct foo : unpack<Packed>::type...{};
Packed
不是此处的参数包,因此无法在包扩展中使用。
如果您将其更改为:
template<class Packed>
struct foo<packed<Packed...> : unpack<Packed>::type...{};
然后你可以扩展参数包,但现在unpack
只会传递一个类型,并且无法知道它是哪个索引,即N
应该是node<Pn, N>
1}}
要使其工作,您需要将类型参数包与您的values
接近的非整数参数包组合在一起,但是您具有从unpack
派生的间接性node
类型列表。
我认为这是你要求的(在误解node
部分后编辑),使用我的index_tuple
实用程序,可以很容易地被litb的seq
模板替换相似的类型。非整数类型的参数包被推导为默认模板参数,然后可以在foo
的基类列表中使用:
#include <redi/index_tuple.h>
template<typename T, unsigned N> struct node { };
template<typename... T> struct packed { };
template<typename T>
struct index_tuple_from_packed;
template<typename... T>
struct index_tuple_from_packed<packed<T...>>
{
typedef redi::to_index_tuple<T...> type;
};
template<typename T, typename I = typename index_tuple_from_packed<T>::type>
struct foo;
template<typename... T, unsigned... Indices>
struct foo<packed<T...>, redi::index_tuple<Indices...>>
: node<T, Indices>...
{ };
struct A { };
struct B { };
struct C { };
int main()
{
typedef packed<A, B, C> p;
foo<p> d;
node<A, 0>* a = &d;
node<B, 1>* b = &d;
node<C, 2>* c = &d;
}
答案 2 :(得分:1)
第二次尝试......
专门化foo
接受特殊标记类型是否可以接受,该类型传入类型和相应的索引?
template<typename T, unsigned N>
struct tagged_node
{ };
template<typename...>
struct foo;
// specialize for case where pack is list of special tag types.
template<typename... T, unsigned... N>
struct foo<tagged_node<T, N>...> : node<T,N>...
{ };
template<typename T, unsigned N>
struct wrapped_node
{ typedef node<T, N> type; };
template<typename T, typename U>
struct make_node_foo_impl;
template<typename... T, unsigned... I>
struct make_node_foo_impl<packed<T...>, index_tuple<I...>>
{
typedef foo<tagged_node<T, I>...> type;
};
template<typename... T>
struct make_node_foo
: make_node_foo_impl<packed<T...>, to_index_tuple<T...>>
{ }; // inherits 'type'
(未经考验,对不起,我得出去!)