繁体   English   中英

循环依赖项(typedef上的类,classdef上的typedef),正向声明给出了模糊的调用?

[英]circular dependency (class on typedef, typedef on class), forward declaration gives ambigous call?

我试图为以下循环依赖找到可接受的解决方案:

template<typename T>
struct Y {
  void f(T&) {}
};

template<typename T, typename U>
struct X : public Y<T>, public Y<U> {};

struct A;
struct B;
typedef X<A,B> Z;

struct A {
  void g(Z& z) {
    z.f(*this);
  }
};

struct B {
  void g(Z& z) {
    z.f(*this);
  }
};

int main(int argc, char** argv) {
  Z z;
  A a;
  B b;
  a.g(z);
  b.g(z);
}

在代码中,Z依赖于A和B,而A / B依赖于Z。A/ B无法转换为模板类定义。 当我向前声明A和B(如图所示)时,我得到一个模棱两可的调用,大概是因为typedef用不完整的类型实例化了X?

当然,我可以简单地将X定义为以下内容,并且一切正常:

struct A;
struct B;

struct X {
  void f(A&) {}
  void f(B&) {}
};

typedef X Z;

struct A {
  void g(Z& z) {
    z.f(*this);
  }
};

struct B {
  void g(Z& z) {
    z.f(*this);
  }
};

int main(int argc, char** argv) {
  Z z;
  A a;
  B b;
  a.g(z);
  b.g(z);
}

...但是当X是模板时如何将Z定义为typedef?

不,不是因为类型不完整。 在使用该成员函数之前,不会实例化该成员函数定义。 成员的声明是,但是类型不完整不会使声明格式错误。 更不用说,您不会以任何不正确的方式使用该类型。

这只是名称查找规则的伪像。 您可以提供using声明,将这些f成员拉入X

template<typename T, typename U>
struct X : public Y<T>, public Y<U> {
    using Y<T>::f;
    using Y<U>::f;
};

这解决了歧义。

这与循环依赖无关,但与多重继承无关。 叮当声很明显:“错误:在不同类型的多个基类中发现成员'f'”。

一种解决方案是消除f含义:是从Y<T>继承的那个还是从Y<U>继承的那个:

z.Y<A>::f(*this);

z.Y<B>::f(*this);

我认为另一种解决方案是合理的,但有点麻烦:

template<typename T>
struct Y {
  void f(T&) {}
};

template<typename T, typename U>
struct X : public Y<T>, public Y<U> {
  template<typename V>
  void f(V& v) {
    this->Y<V>::f(v);
  }
};

struct A;
struct B;
typedef X<A,B> Z;

struct A {
  void g(Z& z) {
    z.f(*this);
  }
};

struct B {
  void g(Z& z) {
    z.f(*this);
  }
};

int main(int argc, char** argv) {
  Z z;
  A a;
  B b;
  a.g(z);
  b.g(z);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM