473,624 Members | 2,601 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

template recursion depth


Hi,

I want to write a template class that holds another class that uses the
same template. This recursion should stop after a predefined number. I
think it's either impossible or easy, but I have no idea right now :-(

A simplified version is here:

template< unsigned Depth >
class Foo
{
public:
list<int> GetList( const char* word )
{
return foo[*word].GetList( word + sizeof( char ) );
}
private:
Foo< Depth - 1 > foo[27];
};

template<>
class Foo<0>
{
public:
list<int> GetList( const char* word )
{
return _list[*word];
}
private:
list<int> _list[27];
};

The compiler runs through, but I get a stack overflow before main( ) is
reached. It is like a multidimensiona l lookup table and the number of
dimensions should be determined by a template parameter. The compiler
should be able to inline as much as possible, therefore I don't use
inheritance, virtual functions etc.

I think the point is, how can I prevent the compiler to include Foo<-1>
in Foo<0> ? I bet there is a special trick.

thanks for any help

Ingo
Jul 23 '05 #1
4 2216
"Ingo Nolden" <in**********@S PAMrecurdyn.org > wrote...
I want to write a template class that holds another class that uses the
same template. This recursion should stop after a predefined number. I
think it's either impossible or easy, but I have no idea right now :-(

A simplified version is here:

template< unsigned Depth >
class Foo
{
public:
list<int> GetList( const char* word )
{
return foo[*word].GetList( word + sizeof( char ) );
'sizeof(char)' is always 1. There is no sense to spell it out. Just
write 1.
}
private:
Foo< Depth - 1 > foo[27];
};

template<>
class Foo<0>
{
public:
list<int> GetList( const char* word )
{
return _list[*word];
}
private:
list<int> _list[27];
};

The compiler runs through, but I get a stack overflow before main( ) is
reached.
How many instantiations are you trying to create? Where is the code
that *uses* your Foo template?

Remember that the size of Foo<N> grows exponentially. The Foo<0> has
27 objects of type 'list<int>'. Even if 'list<int>' is only 4 bytes
long, it's 108 bytes. Foo<1> has 27 Foo<0>'s, that's about 3K. Next
level (Foo<2>) is 78K, next is 2M, next is 55M. Foo<5> is about 1.5G.
Shall I continue or can you do it yourself?
It is like a multidimensiona l lookup table and the number of dimensions
should be determined by a template parameter. The compiler should be able
to inline as much as possible, therefore I don't use inheritance, virtual
functions etc.

I think the point is, how can I prevent the compiler to include Foo<-1> in
Foo<0> ? I bet there is a special trick.


You already are using that "trick". It's called "specialization ".

V
Jul 23 '05 #2

'sizeof(char)' is always 1. There is no sense to spell it out. Just
write 1.


ok, in the real 'not simplified' code it is sizeof( CharT ) and it may
be parameterized to be something else.
I actually expected if I write 1 someone would tell me that it may be a
problem when switching to a different char type.
But you're right, since I spelled it char and not CharT...
}
private:
Foo< Depth - 1 > foo[27];
};

template<>
class Foo<0>
{
public:
list<int> GetList( const char* word )
{
return _list[*word];
}
private:
list<int> _list[27];
};

The compiler runs through, but I get a stack overflow before main( ) is
reached.

How many instantiations are you trying to create? Where is the code
that *uses* your Foo template?

ok, this is important of course

it was:

WordStore<CharU se, 5> store;

and I didn't think 5 is much
Remember that the size of Foo<N> grows exponentially. The Foo<0> has
27 objects of type 'list<int>'. Even if 'list<int>' is only 4 bytes
long, it's 108 bytes. Foo<1> has 27 Foo<0>'s, that's about 3K. Next
level (Foo<2>) is 78K, next is 2M, next is 55M. Foo<5> is about 1.5G.
Shall I continue or can you do it yourself?

but I had to reduce it to Foo<2> to make it >not crash<. I have to admit
that I am a little ashamed not to have tried Foo<2>.
Also I have to admit that I didn't really use int but a
list<WordCounte ryCharT> > where WordCounter is holding an unsigned and a
CharT*

How much memory can I expect an empty list to consume? If it is 40
bytes, Foo<3> should use about 20M. Is that too much for a static
memory? Any if it is, should it cause a stack overflow?

It is like a multidimensiona l lookup table and the number of dimensions
should be determined by a template parameter. The compiler should be able
to inline as much as possible, therefore I don't use inheritance, virtual
functions etc.

I think the point is, how can I prevent the compiler to include Foo<-1> in
Foo<0> ? I bet there is a special trick.

You already are using that "trick". It's called "specialization ".

I know I am using specialization. However I didn't expect it to work,
since it seems 'magic' to me and I have not much experience using it
this way.
So, if one could tell me by what rule the compiler did not include the
foo[] for instanciations of Depth = 0, that would take me a good step
forward along the way to understand c++ and meta programming ( it is
meta programming right? )

On the other hand, I would like to have one level more. 20MB is not soo
much memory, I have 1Gb on a WinXP system. Is there a limitation for
static allocetions independant from the hardware and averything else?

And does anybody know, how much memory an empty std::list needs and how
much it uses for any item additionally to the memory for the item
itself? Ok, that may be implementation dependant but any hints are
welcome. I use VC7.1

cheers
Ingo

Jul 23 '05 #3
"Ingo Nolden" <in**********@S PAMrecurdyn.org > wrote...
[...]
I think the point is, how can I prevent the compiler to include Foo<-1>
in Foo<0> ? I bet there is a special trick.

You already are using that "trick". It's called "specialization ".

I know I am using specialization. However I didn't expect it to work,
since it seems 'magic' to me and I have not much experience using it this
way.


No magic. The process of instantiation has to check whether there are
specialisations and if there are, use them instead of generating the
type from the original template.
So, if one could tell me by what rule the compiler did not include the
foo[] for instanciations of Depth = 0, that would take me a good step
forward along the way to understand c++ and meta programming ( it is meta
programming right? )
Since you defined what Foo<Depth == 0> should look like, why should the
compiler "include" anything not in your definition of it?
On the other hand, I would like to have one level more. 20MB is not soo
much memory, I have 1Gb on a WinXP system. Is there a limitation for
static allocetions independant from the hardware and averything else?
If your compiler reports stack overflow during the creation of your
template "chain", it's a limitation of the compiler (the compiler is
just another program with its own memory allocations and algorithms).
You can find more information in a newsgroup dedicated to that compiler.
Try microsoft.publi c.vc.language.
And does anybody know, how much memory an empty std::list needs
#include <list>
#include <iostream>
int main() {
std::list<int> emptylist;
std::cout << "Empty: " << sizeof emptylist << std::endl;
}
and how much it uses for any item additionally to the memory for the item
itself?
#include <list>
#include <iostream>
int main() {
std::list<int> mylist;
std::cout << "Empty: " << sizeof mylist << std::endl;
mylist.push_bac k(42);
std::cout << "After one insertion: " << sizeof mylist << std::endl;
}

although I bet you the size of the object doesn't change since all
elements of a list are kept outside of the object itself, and you
will need some other methods to find out how much additional memory
such allocation requires.
Ok, that may be implementation dependant but any hints are welcome. I use
VC7.1


microsoft.publi c.vc.language

V
Jul 23 '05 #4

Since you defined what Foo<Depth == 0> should look like, why should the
compiler "include" anything not in your definition of it?
Ok, thats clear. I think I got it now. Indeed its not so magic :-)
On the other hand, I would like to have one level more. 20MB is not soo
much memory, I have 1Gb on a WinXP system. Is there a limitation for
static allocetions independant from the hardware and averything else?

If your compiler reports stack overflow during the creation of your
template "chain", it's a limitation of the compiler (the compiler is
just another program with its own memory allocations and algorithms).
You can find more information in a newsgroup dedicated to that compiler.
Try microsoft.publi c.vc.language.

My compiler never reported anything. This is what I meant by 'compiler
runs through'. It is when I started the program I got stack overflow
before main( ) has been reached. But anyway, you may be right that this
is compiler related.
And does anybody know, how much memory an empty std::list needs

#include <list>
#include <iostream>
int main() {
std::list<int> emptylist;
std::cout << "Empty: " << sizeof emptylist << std::endl;
}


Thank you for that hint. But that is clear. I expected the list to use
additional dynamic memory outside of what I could measure with sizeof.

and how much it uses for any item additionally to the memory for the item
itself?

#include <list>
#include <iostream>
int main() {
std::list<int> mylist;
std::cout << "Empty: " << sizeof mylist << std::endl;
mylist.push_bac k(42);
std::cout << "After one insertion: " << sizeof mylist << std::endl;
}

although I bet you the size of the object doesn't change since all
elements of a list are kept outside of the object itself, and you
will need some other methods to find out how much additional memory
such allocation requires.

That's what I mean. I think sizeof is always resolved at compile time.

thank you anyway

Ingo

Jul 23 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
44945
by: Georgy Pruss | last post by:
Sometimes I get this error. E.g. >>> sum = lambda n: n<=1 or n+sum(n-1) # just to illustrate the error >>> sum(999) 499500 >>> sum(1000) ............ RuntimeError: maximum recursion depth exceeded
4
2574
by: Dan | last post by:
I've encountered some strange behavior in a recursive procedure I'm writing for a bill of materials. First let me ask directly if what I think is happening is even possible: It seems like the procedure is not following the recursion in serial order, but in parallel. In other words, after one instance of the procedure calls itself, it continues executing lines below the recursion before the recursion is done. Is that possible? I...
2
1737
by: Martin Gernhard | last post by:
Hi, I'm trying to use expression templates to calculate values at compile time. Doing it with just one parameter is no problem: ///Begin Listing 1 #include <iostream> using namespace std; template <int n> void UNROLL(){
10
3794
by: MakeMineScotch | last post by:
What's the secret to writing recursive functions that won't crash the computer?
5
3599
by: mast2as | last post by:
Hi guys Here's the class I try to compile (see below). By itself when I have a test.cc file for example that creates an object which is an instance of the class SpectralProfile, it compiles fine. 1 / Now If I move the getSpectrumAtDistance( const T &dist ) method definition in SpectralProfofile.cc let's say the compiler says core/profile.cc:199: error: `kNumBins' was not declared in this scope
13
4515
by: robert | last post by:
My code does recursion loops through a couple of functions. Due to problematic I/O input this leads sometimes to "endless" recursions and after expensive I/O to the Python recursion exception. What would be a good method to detect recursion loops and stop it by user-Exception (after N passes or some complex criteria) without passing a recursion counter parameter through all the funcs? Robert
6
2932
by: Andre Kempe | last post by:
hej folks. i have a heap with fixed size and want to determine the depth of a element with given index at compile-time. therefore i wrote some templates. however, when i use template index_properties<unsigned int>, i get a compiler-error, complaining about the template-recursion of __index_properties__. when i add a partially specialized template (the three commented lines) to stop the template-recursion, it works. does anyone how to...
2
1761
by: vectorizor | last post by:
Hello all, I am attempting to vectorize few template functions with the Intel compiler, but without much success so far. Ok granted, this question is not 100% c++, but it is related enough that I felt I could post it here. Also, I did ask in the Intel forums, without much success. And maybe there are some c++ coders in here that are familiar with the Intel compiler. The code below highlights the problem I have. Essentially, I have a
6
17842
by: globalrev | last post by:
i received an error maximum recursion depth when processing large amounts of data. i dont know exactly how many recursive calls i made but id assume 50000 or so. is there a definitie limit to the nbr of calls or is the memory that runs out? is that then the RAMmemory? is there a special amount of memory assigned for python or it just takes and takes until windows runs out of it?
0
8685
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8633
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8348
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8493
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6112
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4084
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2613
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1797
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1493
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.