解决循环C ++模板依赖关系

时间:2012-02-17 18:46:33

标签: c++ templates mutual-recursion

假设我有:

template<typename T>
class A { 
  typedef T 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 > > a_with_b;
typedef A<C<A > > a_with_C;

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

如何解析typedef a_with_b

我想这样做是因为A有一个回调给B,而B有一个回调给A.例如,A会调用B.do_work(),最后B会调用A.done_work()。此外,这些都是异步调用,所以我不能简单地调用B.do_work()并等到B返回“完成”,因为A在此期间还有其他重要的工作要做。

我不能让A引用B的原因是因为可以有其他实现替换B,例如C。

2 个答案:

答案 0 :(得分:2)

  

我想这样做,因为A有一个回调到B,而B有一个回调给A.例如,A会调用B.do_work(),最后B会调用A.done_work()。

理想情况下,你首先要避免相互依赖,例如:

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);

答案 1 :(得分:1)

你不能。

在您的情况下,其中至少有一个不能是模板。

在这种情况下,您确定需要模板吗?如果两个类A和B或A和C紧密耦合,一个显式引用另一个,那么很明显,模板不应该用在类B和C上,因为你不能用任何东西专门化这些类。否则不会破坏你的整个回调魔法。

顺便说一下,像sigc ++这样的回调库可能就是你所需要的。