For one of my projects, what I really wanted to do was this (simplifying it to the bare minimum);
struct Move
{
int src;
int dst;
};
struct MoveTree
The C++ Standard (2003) clearly says that instantiating a standard container with an incomplete type, invokes undefined-behavior.
The spec says in §17.4.3.6/2,
In particular, the effects are undefined in the following cases:
__ [..]
— if an incomplete type (3.9) is used as a template argument when instantiating a template component.
__ [..]
Use a pointer to the type in the Vector, this will be portable.
struct Move
{
int src;
int dst;
};
struct MoveTree;
struct MoveTree
{
Move move;
std::vector<MoveTree*> variation;
};
MoveTree
is an incomplete type inside its definition. The standard does not guarantee instantiation of STL templates with incomplete types.
You should define copy constructors and assignment operators for both Move
and MoveTree
when using vector, otherwise it will use the compiler generated ones, which may cause problems.
The MoveTree
elements in std::vector
are in an allocated (as in new []
) array. Only the control information (the pointer to the array, the size, etc) are stored within the std::vector
within MoveTree
.
No, it's not portable. codepad.org does not compile it.
t.cpp:14: instantiated from here
Line 215: error: '__gnu_cxx::_SGIAssignableConcept<_Tp>::__a' has incomplete type
compilation terminated due to -Wfatal-errors.