简体   繁体   English

C++ 中模板的循环引用,当需要完整类型时

[英]Circular reference of templates in C++, when complete types are required

Consider this example in C#:考虑 C# 中的这个例子:

class C<T> {
   
   void greetMe() { print("Hello you"); }
}

class D : C<E> {
   void useE(E e) {
      e.greetMe();
   }
}

class E : C<D> {
   void useD(D d) {
      d.greetMe();
   }
}

Is an equivalent construction possible in C++ using templates?在 C++ 中是否可以使用模板进行等效构造?

I don't have any useful C++ code to show, since my interest in this is purely academic.我没有任何有用的 C++ 代码可显示,因为我对此的兴趣纯粹是学术性的。 You can consider this code as pseudocode.您可以将此代码视为伪代码。

For the curious: I was examining restrictions of eager languages to handle circular references, as opposed to lazy languages.对于好奇的人:我正在研究急切语言处理循环引用的限制,而不是惰性语言。 I remembered that something like this is possible in C#'s type system, which I'm attempting to view as a statically checked lazy language.我记得在 C# 的类型系统中可能会有这样的事情,我试图将其视为一种静态检查的惰性语言。 I remembered that C++'s templates are the exact opposite (but still somewhat functional?), which I thought might be an interesting study.我记得 C++ 的模板是完全相反的(但仍然有些功能?),我认为这可能是一项有趣的研究。
Thank you for your time!感谢您的时间!

Related question 相关问题

Extending from Not A Number's answer to the related question and embedding comments where I felt it was necessary:从 Not A Number 的答案扩展到相关问题并在我认为有必要的地方嵌入评论:

template <class T>
class C {
public:
   void greetMe() {  }
};

class E; // forward declare E same as answer to related question
class D : public C<E> {
   void useE(E & e); // Passing by reference should be similar to the behaviour 
                     // of the C# program
                     // only declare function. Fully define later after D is complete
};

class E : public C<D> {
   void useD(D & d) { //D is already complete; we can safely define here
      d.greetMe();
   }
};

// now we can define D's implementation of useE 
void D::useE(E & e) {
   e.greetMe();
}

You cannot have a complete type before it is defined, because the definition is what makes the type complete.在定义之前,您不能拥有完整的类型,因为定义是使类型完整的原因。

There may never be a cycle in the dependency graph.依赖图中可能永远不会有循环。

That said, the class D does not require E to be complete.也就是说,class D不需要E是完整的。 Only the definition of D::useE depends on that definition.只有D::useE的定义取决于该定义。 So, following order of definition satisfies all dependencies: D , E , D::useE .因此,以下定义顺序满足所有依赖项: DED::useE

template <class T>
struct C {
   void greetMe();
};

struct E;
struct D : C<E> {
   void useE(E e);
};

struct E : C<D> {
   void useD(D d) {
      d.greetMe();
   }
};

void D::useE(E e) {
    e.greetMe();
};

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

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