c++templatesmutual-recursion

Resolve circular C++ template dependency


Suppose I have:

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

How do I resolve the typedef a_with_b?

I want to do this because A has a callback to B, and B has a callback to A. For example, A would call B.do_work(), and eventually B would call A.done_work(). Furthermore, these are each asynchronous calls, so I cannot simply call B.do_work() and wait until B returns "done" because A has other important work to do in the meantime.

The reason I can't just have A take a reference to B is because there can be other implementations that replace B, such as C.


Solution

  • I want to do this because A has a callback to B, and B has a callback to A. For example, A would call B.do_work(), and eventually B would call A.done_work().

    Ideally you'd avoid the interdepencies in the first place, e.g.:

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