模板 struct A { typedef float atype; typedef typename tB :: btype typeB; }; 模板 struct B { typedef float btype; typedef typename tA :: atype typeA; };
struct MyB;
struct MyA: public A<MyB>{};
struct MyB: public B<MyA>{};
int main(int argc, char *argv[])
{
}
不编译因为 “main.cpp:6:错误:无效使用不完整类型'struct MyB'”。
基本上编译器无法解决循环因为定义 A取决于B的定义,反之亦然。 有没有办法解决这个问题? 感谢,
答案 0 :(得分:3)
这无法直接解决。昨天发布了一个非常相似的问题(尽管不涉及模板):C++: How can I avoid "invalid covariant return type" in inherited classes without casting?
您的两个选择是重新设计您的解决方案,以便不再需要这种交叉依赖关系,或重新设计您的解决方案,以便您只使用模板参数来声明引用和指针(因为它们的声明不需要该类型的完整定义在当时可用)。
答案 1 :(得分:1)
我认为既然你是typedef'ing tB :: btype,编译器就需要知道结构类型的MyB,它没有(你只是向前声明它)。 你可以检查一下:事实上,如果你在结构B中注释掉对tA :: atype的引用,你仍会得到相同的错误,而如果你在结构A中注释掉typedef typeB,编译器就不会抱怨。
把它放在一边,你确定你需要这种循环依赖吗?
答案 2 :(得分:1)
如果你摆脱模板烟雾屏幕,你在这里涉及无限递归。目前,将继承视为一种略微不同的陈述遏制的方式(它就是这样)。你说myA包含一个myB,而myB又包含一个myA,而myA又包含一个myB,依此类推 - 即任何一种类型的任何单个对象都有无限大小...
编辑:正如litb所指出的,这些结构都不包含任何内容,因此理论上它们不占用任何空间(归功于空基类优化)。虽然这可以防止结构本身具有无限大小,但编译器必须生成的AST仍然是无限的 - 例如,myA :: myB :: myA :: myB: :myA :: myB :: myA :: myB ... myB :: btype(myA::atype
,myA::tA
或myB::tB
的最后一项)是任何级别的有效类型名称筑巢至少在编写通常编写的编译器时,AST中不允许循环,只留下无限的AST。