Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > class containing a list of itself

Reply
Thread Tools

class containing a list of itself

 
 
Old Wolf
Guest
Posts: n/a
 
      08-25-2004
The following code causes a segfault for me, why?

#include <list>

template<typename T>
struct Tree
{
std::list< Tree<T> > child;
};

int main()
{
Tree<int> bar;
std::list< Tree<int> > foo;
foo.push_back(bar);
}

If I reverse the order of the 'foo' and 'bar' declarations then I instead
get a compiler error "Compiler could not generate default constructor
for class Tree<int>". The problem is the same with other types instead of
'int', but if I change list to vector or deque then there is no problem
at all.
 
Reply With Quote
 
 
 
 
Sharad Kala
Guest
Posts: n/a
 
      08-25-2004

"Old Wolf" <> wrote in message
news: om...
> The following code causes a segfault for me, why?
>

[snip]
> If I reverse the order of the 'foo' and 'bar' declarations then I instead
> get a compiler error "Compiler could not generate default constructor
> for class Tree<int>". The problem is the same with other types instead of
> 'int', but if I change list to vector or deque then there is no problem
> at all.


Which compiler are you using ? I can't see both the problems on VC 7.1 and
g++ 3.3.1.

-Sharad


 
Reply With Quote
 
 
 
 
Rob Williscroft
Guest
Posts: n/a
 
      08-25-2004
Old Wolf wrote in news: om in
comp.lang.c++:

> The following code causes a segfault for me, why?
>
> #include <list>
>
> template<typename T>
> struct Tree
> {
> std::list< Tree<T> > child;


Tree< T > is at this point an incomplete type, all the standard library
containers require that there paramiters are complete.

> };
>
> int main()
> {
> Tree<int> bar;
> std::list< Tree<int> > foo;
> foo.push_back(bar);
> }
>
> If I reverse the order of the 'foo' and 'bar' declarations then I
> instead
> get a compiler error "Compiler could not generate default constructor
> for class Tree<int>". The problem is the same with other types instead
> of 'int', but if I change list to vector or deque then there is no
> problem at all.


It just so happens that vector and deque on you implementation *don't*
require a complete type, IOW it may work but it isn't portable.

The good news is this is really a Quality of Implementation issue.
I.e. there is no "good" reason the the standard library containers
*need* to require a complete argument type.

So if you're not worried about having complete portablity you could
upgrade your standard library, both g++ and dinkumware compile
your code without any problem. I don't now about stlport but my
experience with rougewave suggest it will not. But your code will
be non-standard until/unless the standard gets changed.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
 
Reply With Quote
 
Sharad Kala
Guest
Posts: n/a
 
      08-25-2004
> But your code will
> be non-standard until/unless the standard gets changed.


I think Standard does mention about this in Section 14.3.1/2
" ...[Note: a template type argument may be an incomplete type. ] "

-Sharad


 
Reply With Quote
 
Rob Williscroft
Guest
Posts: n/a
 
      08-25-2004
Sharad Kala wrote in news: in comp.lang.c++:

>> But your code will
>> be non-standard until/unless the standard gets changed.


With hindsight I should have possibly been clearer that the requirment
for completeness of argument types, is only for instantiation *not*
for declaration:

#include <list>

struct X;

extern std::list< X > xlist;

struct X {};

std::list< X > xlist;


>
> I think Standard does mention about this in Section 14.3.1/2
> " ...[Note: a template type argument may be an incomplete type. ] "
>



14.3.1 == Templates / Template type arguments.

Not really relevent to wether or not std::list< T > can take
an incomplete T and be instantiated *before* T is complete.

IOW: you can always (*) declare a specialization which has an incomplete
argument type, what is dependant on the template defenition is wether
you can instantiate such a specialization.

*) Unless such a declaration requires instantition of an
un-instantiatable specialization:

template < typename > struct empty {};

template < typename T, typename U = typename empty< T >::type >
struct no
{
};

extern no< int > nope;

Rob.
--
http://www.victim-prime.dsl.pipex.com/
 
Reply With Quote
 
tom_usenet
Guest
Posts: n/a
 
      08-25-2004
On Wed, 25 Aug 2004 19:47:50 +0530, "Sharad Kala"
<> wrote:

>> But your code will
>> be non-standard until/unless the standard gets changed.

>
>I think Standard does mention about this in Section 14.3.1/2
>" ...[Note: a template type argument may be an incomplete type. ] "


17.4.3.6 Other functions
1 In certain cases (replacement functions, handler functions,
operations on types used to instantiate standard library template
components), the C + + Standard Library depends on components supplied
by a C + + program. If these components do not meet their
requirements, the Standard places no requirements on the
implementation.
2 In particular, the effects are undefined in the following cases:
[snip]
— if an incomplete type (3.9) is used as a template argument when
instantiating a template component.

Tom
 
Reply With Quote
 
Old Wolf
Guest
Posts: n/a
 
      08-26-2004
tom_usenet <> wrote:
>
> 2 In particular, the effects are undefined in the following cases:
> [snip]
> ? if an incomplete type (3.9) is used as a template argument when
> instantiating a template component.


I think I am confused about the meaning of "instantiating"?

> #include <list>
>
> template<typename T>
> struct Tree
> {
> std::list< Tree<T> > child;

^^^^^^^^^^^^^^^^^^^^^^^^^^^^
declaration (no objects are yet created)

> };
>
> int main()
> {
> Tree<int> bar;

^^^^^^^^^^^^^^
instantiation (a 'Tree<int>' object is created, which involves
creation of any sub-objects of Tree<int>).
Surely at this point, Tree<int> is a complete type,
so std::list< Tree<int> > would be OK.

> std::list< Tree<int> > foo;
> foo.push_back(bar);
> }

 
Reply With Quote
 
Rob Williscroft
Guest
Posts: n/a
 
      08-26-2004
Old Wolf wrote in news: om in
comp.lang.c++:

> tom_usenet <> wrote:
>>
>> 2 In particular, the effects are undefined in the following cases:
>> [snip]
>> ? if an incomplete type (3.9) is used as a template argument when
>> instantiating a template component.

>
> I think I am confused about the meaning of "instantiating"?


Its when a template (class or function) is used to create a new
type or function (a specialization in standardeze).

>
>> #include <list>
>>
>> template<typename T>
>> struct Tree
>> {
>> std::list< Tree<T> > child;

> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> declaration (no objects are yet created)


Correct, and the declaration isn't the problem.

>
>> };
>>
>> int main()
>> {
>> Tree<int> bar;

> ^^^^^^^^^^^^^^
> instantiation (a 'Tree<int>' object is created, which involves
> creation of any sub-objects of Tree<int>).


Yes, however the type "Tree< int >" isn't *complete* until
instantiation is finnished.

> Surely at this point, Tree<int> is a complete type,
> so std::list< Tree<int> > would be OK.


Yes, but instantiating Tree< int > requires that Tree< int >
be *complete* before Tree< int > is instantiated, a catch 22,
as a template isn't complete until its been instantiated.

>
>> std::list< Tree<int> > foo;
>> foo.push_back(bar);
>> }

>


Note: with class templates "complete" and "instantiated" are
equvalent terms, however non-templates can also be incomplete:

struct X; /* incomplete */
struct x {}; /* complete */

Rob.
--
http://www.victim-prime.dsl.pipex.com/
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Why doesn't python's list append() method return the list itself? dhruvbird Python 16 07-16-2010 05:40 PM
obtain element name, or attribute and value of the document name itself, and some elemnts and attributes from an ancestor or the node itself using xquery Jeff Kish XML 4 10-30-2008 05:47 PM
convert string containing list to list (or tuple) type Poppy Python 1 05-30-2008 02:17 PM
how to erase a list member with just an iterator (without the list itself)? alon C++ 6 01-15-2007 11:17 AM
class X containing an stl list<X> in MS Visual C++ Joseph Lanctot C++ 1 06-21-2004 06:35 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57