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

タプルの要素を「packed」して、「unack」を介した間接的な基本クラスではなく、「foo」の直接的な基本クラスにすることに興味があります。また、タイプタプルの要素は、異なる非プリミティブタイプと非ファイナルタイプです。

例をより詳細にするには、

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

私が興味を持っているのは、 sfooから直接派生する必要があるということです。node

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

2回目の試行...

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 に答える
1

NBあなたの質問のこの部分は不可能です:

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から派生するという間接性があります。unpacknode

これは、litbのテンプレートまたは同様のタイプに簡単に置き換えることができる私のユーティリティを使用して、あなたが求めているものだと思います(node一部を誤解した後に編集) 。整数の非型パラメータ パックは、デフォルトのテンプレート引数として推定され、次の基本クラス リストで使用できます。index_tupleseqfoo

#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 に答える