2012-02-17 17 views
2

は、私が持っていると仮定しますか?円形C++テンプレート依存性を解決

AにはBへのコールバックがあり、BにはAへのコールバックがあるため、この処理を行いたいとします。たとえば、AはB.do_work()を呼び出し、BはA.done_work()を呼び出します。さらに、これらはそれぞれ非同期呼び出しなので、私は単にB.do_work()を呼び出すことはできません。その間にAは他の重要な作業があるので、Bが "done"を返すまで待ち​​ます。このようC.

+0

私は彼らがお互いに依存しますが、それは> ...>>なってしまう問題を回避します。 –

+6

ユースケースに関して拡張できますか?可能性として、根底にある問題に別々にアプローチすることができます。 –

+2

あなたが説明することを行うために* is-a *関係は必要ありません。 AにBへの参照があり、BにAへの参照がある場合は、簡単にコールバックを行うことができます。 –

答えて

2

AにはBへのコールバックがあり、BにはAへのコールバックがあるため、この処理を行いたいとします。たとえば、AはB.do_work()を呼び出し、BはA.done_work()を呼び出します。

理想的には、例えば、最初の場所でinterdepenciesを避けたい:

template<class T> struct A { 
    std::function<void (T)> handler; 
    void f(T) {} 
    void work() { handler(T()); } 
}; 
template<class T> struct B { 
    std::function<void (T)> fn; 
    void f(T) {} 
    void work() { handler(T()); } 
}; 

// .. 
A<int> a; 
B<int> b; 
a.handler = std::bind(&B::f, &b); 
b.handler = std::bind(&A::f, &a); 
+0

別途定義された補完ハンドラが問題を回避します。ありがとう! –

+0

ニース!おそらく 'B :: fn'の代わりに' B :: handler'でしょう。また、 'A :: f'と' B :: f'を 'bind'に指定しなければなりませんでした。 – robsn

1

あなたができないようにBを交換する他の実装が存在し得るので、私はちょうどBへの参照を取ることはできません

理由があります。

少なくとも1つはあなたのケースのテンプレートであってはなりません。

この場合、テンプレートが必要ですか? 2つのクラスAとBまたはAとCが密接に結合されていて、明示的に別のクラスを参照している場合は、クラスBとクラスCでテンプレートを使用しないでください。あなたの全体のコールバック魔法を壊さずに。ところで

、SIGCなどのコールバックライブラリは++何が必要かもしれません。

+0

あなた** **できます。私の答えを見てください。 – atablash

0

私はこのケースでは、より良い形消去std::functionアプローチを好むが、あなたの元のコードを作成することが可能です仕事

Aを定義するためにテンプレートテンプレートパラメータを使用します。

template<template<typename> typename T> 
class A { 
    typedef T<A> t_type; 
    void done_work(); 
}; 

template<typename T> 
class B { 
    typedef T t_type; 
    void do_work(){ 
    // adds work to an asynchronous event queue, eventually T.done_work() is called 
    } 
}; 

template<typename T> 
class C { 
    typedef T t_type; 
    void do_work(){ 
    // adds work to an asynchronous event queue, eventually T.done_work() is called 
    } 
}; 

typedef A<B> a_with_b; 
typedef A<C> a_with_c; 

int main(int argc, char** argv){ 
    a_with_b awb; 
    a_with_c awc; 
} 

注意だけでいくつかの変更があること。今Aではなくタイプテンプレートをとります。

BCが変更されていないことに注意してください。

関連する問題