以下代码无法编译。: -
#include <vector>
template <typename T>
struct B;
template <typename T>
struct A
{
B<T> _a;
};
template <typename T>
struct B
{
A<T> _b;
};
int main()
{
B<int> c;
return 0;
}
从第一眼看,原因接缝是A和B之间的循环依赖。但是当使用显式地使用类型B _b成员时,使用向量(存储实际对象而不是指向它的指针)。喜欢这个
#include <vector>
template <typename T>
struct B;
template <typename T>
struct A
{
std::vector<B<T>> _a;
};
template <typename T>
struct B
{
A<T> _b;
};
int main()
{
A<int> c;
return 0;
}
,一切正常。问题是为什么?如果向量仅需要B的大小,则T>结构也是第一个例子中A的任何部分,因为它不会调用任何B的函数。
答案 0 :(得分:2)
在第一个示例中,sizeof(A<int>)
和sizeof(B<int>)
是递归定义的。
问问自己:什么是sizeof(A<int>)
?
您无法回答,因为sizeof(A<int>)
依赖于sizeof(B<int>)
并递归。
在第二个示例中,sizeof(A<int>)
是sizeof(std::vector<B<int>>)
,它是常量,实际上std::vector
执行堆分配。
尝试将std::vector
替换为std::array
,您将再次遇到同样的问题。实际上std::array
的大小取决于元素的大小。
答案 1 :(得分:1)
std::vector
的实现显然只有B<T>
成员的指针和/或引用。由于引用和指向不完整类型的指针是合法的,因此程序可以正确编译。