使用C ++中的一个模板解决循环依赖

时间:2013-10-17 08:13:34

标签: c++ templates

这看起来很简单,但我无法解决这个问题。最小的例子:

template<class T>
struct C {
    typename T::t var;
};

class B;
struct A : public C<B> {
    typedef int t;
};

struct B
{
    A a;
};

int main() { return 0; }

我知道可以通过给予C少于B来解决它:

template<class t>
struct C {
    t var;
};

struct A : public C<int> {
};

但是这并不满足(特别是因为B有很多这样的typedef和我在C中真正需要的静态函数)。有什么更好的办法解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

如果您可以将A设为模板,则以下内容应该有效...

template<class T>
struct C {
    typename T::t var;
};

template <typename BaseType>
struct A : public C<BaseType> {
  int i;
};

struct B
{
  typedef int t;
  A<B> a;
};


typedef A<B> AType;

int main() {

  AType a;
  a.i = 1;
  a.var = 1;
  B c;
  c.a.i =0;

  return 0;

}

答案 1 :(得分:1)

首先,如果你想让一个类成为一个基类,那么它的类型必须是完整的,比如

struct A : public C<B> 

在这种情况下,B必须是完整的类型。

其次,如果声明一个类类型成员,除非你定义一个指针,否则它的类型需要完整。

struct B
{
    A a;  // A must be complete type
};

因此,您不能A继承BB作为成员。但你可以将一个转换为指针。对于样品,下面应该没问题:

class A;

struct B
{
    A* a;           // imcomplete type is fine
    typedef int t;
};

struct A : public C<B> {         
};

通常,如果您遇到此类问题,则表示您的课程中存在设计问题。也许你正在制作monolith classes

如果您遵循良好的指导方针:

1 one class (or function), one responsibility. 
2 Where possible, prefer writing functions as nonmember nonfriends.

你会遇到这类问题。