Greg wrote:
>
Kai-Uwe Bux wrote:
>al*****@pisem.net wrote:
In need to implement a tree structure in which every node has arbitrary
number of children the following code has come into mind:
using std::list;
template < class Contents class Tree_node{
Contents cn;
list < BTree_node < Contents children;
.......
}
You seem to be running into the trap
class X {
std::list< X some_member;
};
Unlikely, since the code is question is declaring a class template -
not a class - with the std::list<of its own type as a data member.
>This is not required to compile and if it does, the behavior is
undefined. The reason is that X is incomplete in std::list<X>. It is
regrettable that the standard requires completeness for type arguments in
std::list<>, but it does in [17.4.3.6/2].
But in this case, "X" would be a specialization of a class template.
Therefore, the std::list<data member of X would be instantiated - if
it is instantiated at all - only after an instance of the template
class X itself had been instantiated - which of course requires that X
be a complete type. In other words, X must be a complete type before
its std::list data member could ever be instantiated.
Templates do not by-pass the completeness problem. Consider
template < typename T >
class X {
std::list< X some_member; // (*)
};
On line (*) the type X is incomplete. You are right to observe that X will
be complete, once X<inthas been instantiated. However [14.6/7] kicks in:
...If a type used in a non-dependent name is incomplete at the point at
which a template is defined but is complete at the point at which an
instantiation is done, and if the completeness of that type affects
whether or not the program is well-formed or affects the semantics of the
program, the program is ill-formed; no diagnostic is required. [Note: if a
template is instantiated, errors will be diagnosed according to the other
rules in this Standard. Exactly when these errors are diagnosed is a
quality of implementation issue. ] ...
Thus, if completeness actually mattered with regard to std::list<>, we would
be doomed nonetheless.
Also, this is to be expected. After all
template < typename T >
class X {
std::pair< X, X data;
};
cannot work just because we turned the recursive type bomb into a template.
What is the workaround for this?
(a) Don't bother: fix the typo from BTree_node to Tree_node and hope for
the best. Most implementation of std::list<do actually not require the
type argument to be a complete type. (You might run into trouble with g++
installations that were built with the concept-checks option enabled. So
much for portability.)
I think the type is the only evident problem at this point.
Do you mean "type" or "typo"?
Best
Kai-Uwe Bux