2

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.

4

3 回答 3

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);
于 2012-02-17T19:08:34.457 回答
2

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采用模板而不是类型

还要注意BandC是不变的。

于 2017-11-28T07:30:43.370 回答
1

你不能。

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

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

顺便说一句,你可能需要一个像 sigc++ 这样的回调库。

于 2012-02-17T19:06:00.380 回答