奇怪的模板行为

时间:2016-01-15 13:01:28

标签: c++ templates

以下代码无法编译。: -

#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的函数。

2 个答案:

答案 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>成员的指针和/或引用。由于引用和指向不完整类型的指针是合法的,因此程序可以正确编译。