![]() |
1
4
这是因为实例化表时类ConcreteTable尚未实例化,所以编译器尚未看到t::RT。我不太确定C++标准是如何处理这种递归的(我怀疑它是未定义的),但它并不能像你预期的那样工作(这可能是好的,否则事情会复杂得多——你可以用它来表达逻辑悖论——就像是一个错误的假设,它是真的)。 固定
如果你不坚持RT作为
甚至是外部结构
如果您只希望类型是方法的参数/返回类型,可以通过模板化此方法来实现,例如。
|
![]() |
2
1
为什么不这样做呢?
|
![]() |
3
1
问题是ConcreteTable是根据Table定义的,但如果没有ConcreteTable的定义,则无法定义Table,因此创建了一个循环定义。 看起来在设计类层次结构的方式中可能存在潜在的问题。我猜您要做的是在表的定义中提供操作通用记录类型的方法,但是让ConcreteTable来定义记录类型。更好的解决方案是将记录类型设置为表模板的参数,将ConcreteTable设置为直接子类:
现在您消除了循环依赖,表仍然是基于记录类型进行抽象的。 |
![]() |
4
1
请注意,编译器不允许执行您想要执行的操作。如果可能的话,您可以这样做:
这将是一种类型定义无限循环。 当需要使用一个类的成员时,编译器要求完全定义该类,从而阻止了这种可能性;在这种情况下,表(ConcreteTable中的祖先列表)的模板安装点在RT的定义之前,因此RT不能在表内使用。 解决方案需要一个中间类来避免相互依赖,其他人已经说过了。 |
![]() |
5
1
什么时候
|
![]() |
6
1
我认为其他人都很好地涵盖了这一点,我只是想补充一点,我认为从自我的模板中继承,然后试图修补一些东西,使其发挥作用,这是一种不好的做法。我将采用另一种方法,将记录类型(RT)作为参数,而不是ConcreteTable本身。如果您曾经查看过std::iterator类,它使用的方法与此完全相同:
当子类从迭代器继承时,它会执行以下操作:
如果您想对ConcreteTable子类进行更多的专门化,您可以始终重写表中的方法,以及使用模板参数。 |
![]() |
7
1
在完全定义类之前,您试图将类CponcreateTable用作模板参数。 以下等效代码可以正常工作:
|
![]() |
TCD · 标准库非类型模板类是否显式实例化? 2 年前 |
![]() |
sovesti · 参数较少的模板函数中的演绎 2 年前 |
![]() |
KiraHoneybee · 具有构造函数参数的模板化类 3 年前 |
![]() |
Seymore Glass · 模板不工作的默认参数 3 年前 |
![]() |
Alexander Daum · 模板参数中对模板类型的引用 7 年前 |
![]() |
ledonter · 为什么注入的类名有时不被视为类模板中的模板名? 7 年前 |