2012-02-15 9 views
6

古い質問を維持する。解決方法については以下を参照してください。 これはおそらく単純なことですが、まだまだです。C++ 11可変テンプレートテンプレートパラメータ

#include <vector> 

template <typename... Ts> 
struct typelist 
{ 
}; 

template <typename T> 
struct EventContainer 
{ 
    typedef T Type; 
    /// TODO. Ring buffer 
    std::vector<T> container; 

    void push(const T& t) 
    { 
     EventContainer<T>::container.push_back(t); 
    } 

    virtual ~EventContainer() 
    { 
    } 
}; 


template <template <typename...> class TL> 
class EventStorage: 
     public EventContainer<Ts>... 
{ 

}; 

class Event1 
{ 
}; 

class Event2 
{ 
}; 

typedef typelist<Event1,Event2> Events12; 

int main() 
{ 
    EventStorage<Events12> ev; 

    return 0; 
} 

がどのように私はtypelist内の各タイプにtempleted EventStorage継承EventContainerを行うことができます。私は、次のC++ 11のコード・フラグメントを持っています。私はLoki :: libraryでそれを行うことができましたが、私は可変的なテンプレートでC++ 11を使いたいと思います。 ありがとうございます。

解像度1:固定EventStorageテンプレートテンプレートの問題。これにより、EventStorageが、の各タイプでテンプレート化されたEventContainerのすべてを継承します。

template <typename...> 
class EventStorage 
{ 
}; 

template <typename... Ts> 
class EventStorage < typelist<Ts...> >: 
     public EventContainer<Ts>... 
{ 

}; 

今、私は次のようmain()に、時間エラーをコンパイルしている:

int main() 
{ 
    EventStorage<Events12> ev; 
    Event1 ev1; 
    ev.push(ev1); 

    return 0; 
} 

In function ‘int main()’: 
error: request for member ‘push’ is ambiguous 
error: candidates are: void EventContainer<T>::push(const T&) [with T = Event2] 
error: void EventContainer<T>::push(const T&) [with T = Event1] 

コンパイラが混乱しているのはなぜ?結局、私は特定のタイプでプッシュします。 GCC 4.6.1はこちら。

RESOLUTION2: @Matthieu M.私は転送方式int型EventStorageを提示しますが、1つの余分functinコールのコストで可能で示唆したように:

template <typename T> 
void push(const T& t) 
{ 
    EventContainer<T>::push(t); 
} 

をアレキによると、コンパイラは、このコール転送を最適化しますパラメータが参照である限り。 質問は正式に終了しました:)

答えて

6

最初にtypelistを導入する理由はありますか?

template <typename T> struct Template { void push(T) {} }; 

template <typename... Args> 
class Storage: public Template<Args>... 
{ 
public: 
    // forwarding... 
    template <typename T> 
    void push(T t) { 
    Template<T>& me = *this; 
    me.push(t); 
    } 
}; 

int main() { 
    Storage< int, char > storage; 
} 

このworks、あなたは全体のStorage<...>ビットをtypedefすることができます。

EDIT:タイプを「組み合わせる」可能性についてのコメントに続きます。

template <typename...> struct CombineStorage; 

template <typename... A, typename... B> 
struct CombineStorage<Storage<A...>, Storage<B...>> { 
    typedef Storage<A..., B...> type; 
}; 

それとも単にtypelistにアダプタを提供します:2つの解決策があります

現時点で

template <typename... Args> 
class Storage<typelist<Args...>>: public Storage<Args...> {}; 
+0

私は、さまざまな種類の「イベント」置換を粒状化することができたらいいですね。例えば。 'typedefタイプリスト pumpEvents; ' typedefタイプリスト displayEvents; ' あなたはそれをこのように置くと、2つの 'タイプリスト'を組み合わせることができます。それらを両方とも保存する。 –

+0

「タイプリスト」アダプタとストレージコンビネータを含むように私の答えを編集しました。 –

+0

ありがとうございます。私は、私の他の人からこのあいまいさの問題を解決した後、それを試してみます。それは非常に奇妙です。 'push()'にオーバーロードされていませんか? –

1

は、あなたもちょうどtypelistにEventStorageにtypelistにインスタンスを渡すことはありませんしていますテンプレート。現在のところ、で、展開するタイプパックはありません。

しかし、あなたが専門ではtypelistを解凍することが可能とタイプで動作する必要がありそうパック:

template <typename...> class EventStorage; 

template <typename Head, typename... Tail> class EventStorage<Head, Tail...> 
    : public EventContainer<Head>, EventStorage<Tail...> 
{ 
    using EventContainer<Head>::push; 
    using EventStorage<Tail...>::push; 
}; 

// allows you to pass typelists for convenience 
template <typename... TL> class EventStorage<typelist<TL...>> 
    : public EventStorage<TL...> 
{ 
    using EventStorage<TL...>::push; 
}; 

using宣言だけで動作するように思われる、同じ過負荷セットにすべてpush方法を引っ張ります私のために。

代わりに、this->EventContainer<T>::pushに明示的に転送するテンプレートメソッドを(トップレベルのタイプリストの特殊化にのみ)追加することもできますが、正確なタイプの一致が必要です。

+0

はい、私はそれを自分で考え出しました。しかし、今私はあいまいさを感じる。 'エラー:候補者は次のとおりです:[T =イベント2付き]のボイドEventContainer ::プッシュ(のconst T&)メンバーに対する要求 'プッシュ''エラー ambiguous'ある は/追加は、私はこれを取得、あなたの修正を置き換えると仮定します[T =イベント1を有する] ' '空隙EventContainer ::プッシュ(CONST T&) ' 主である:メイン ' INT(){ \t EventStorage EV。 \t Event1 ev1; \t ev.push(ev1); \t return 0; } –

+0

ええ、私はプッシュビットを追加しませんでしたが、今少し編集が必要です... – Useless

+0

ああ、今少しの誤解があることがわかります。 私は 'タイプリスト 'の各タイプでテンプレート化されたすべての' EventContainer'を継承したいと思っています。私のコードは実際には次のとおりです。 ' テンプレート クラスEventStorage { }; テンプレート<型名... Tsの> クラスEventStorage >: \t \t公共EventContainer ... {}。 ' 編集:sh * tはここでフォーマットできません。私は申し訳ありません:( –