1

我有一个编码为的类型元组

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>{};

我有兴趣将元组“打包”的元素作为“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应该直接从nodes

4

3 回答 3

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
于 2012-06-02T09:10:46.727 回答
1

注意你的这部分问题是不可能的:

template<class Packed>
struct foo : unpack<Packed>::type...{};

Packed这里不是参数包,所以不能在包扩展中使用。如果您将其更改为:

template<class Packed>
struct foo<packed<Packed...> : unpack<Packed>::type...{};

那么你可以扩展参数包,但现在unpack只会传递一个类型,并且无法知道它是哪个索引,即N应该用于什么node<Pn, N>

为了使其工作,您需要将类型参数包与整数的非类型参数包结合起来,您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;
}
于 2012-06-02T11:08:33.593 回答
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'

(未经测试,对不起,我必须出去!)

于 2012-06-02T12:03:37.010 回答