Reputation: 1457
The following code does not compile.:-
#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;
}
From the first look the reason seams to be the circular dependency between A and B. However when instead of using type B _b member explicitly, the vector (storing the actual object and not pointer to it) is used. Like this
#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;
}
, everything is working fine. And the question is why? If vector needed only size of the B,T> structure so is any part of A in first example because it does not invoke any B's functions.
Upvotes: 0
Views: 54
Reputation: 301
In your first example the sizeof(A<int>)
and sizeof(B<int>)
are defined recursively.
Ask yourself: What is the sizeof(A<int>)
?
You can't answer because sizeof(A<int>)
depends on sizeof(B<int>)
and recursively.
In the second example sizeof(A<int>)
is sizeof(std::vector<B<int>>)
which is constant, indeed std::vector
does a heap allocation.
Try to replace std::vector
by std::array
and you'll have the same issue again. Indeed the size of std::array
depends on the size of the elements.
Upvotes: 2
Reputation: 76240
std::vector
's implementation apparently only has pointers and/or references to B<T>
as members. Since references and pointers to incomplete types are legal, the program compiles correctly.
Upvotes: 1