473,769 Members | 2,348 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

template recursion

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_propertie s<unsigned int>,
i get a compiler-error, complaining about the template-recursion of
__index_propert ies__. when i add a partially specialized template (the
three commented lines) to stop the template-recursion, it works.

does anyone how to make it work without this partial specialization? ??

my compiler is microsoft visual studio 2005

thanks in advance
andre
=============== =============== ========
template < unsigned int power , int base >
struct nth_power
{ enum { value = nth_power<power-1,base>::value* base }; };

template < int base >
struct nth_power< 0 , base >
{ enum { value = 1 }; };

template< unsigned int level >
struct level_propertie s {
enum { entries_in_laye r = nth_power<level ,2>::value };
enum { number_entries = nth_power<level +1,2>::value-1 };
enum { index_first_ele ment = number_entries - entries_in_laye r };
};

template< int index , int level >
struct __index_propert ies__ {
typedef level_propertie s<levelthis_lev el;
enum { level = (this_level::nu mber_entries>in dex)? level :
__index_propert ies__<index,lev el+1>::level };
};

// template< int index >
// struct __index_propert ies__<index,20>
// { enum { level = 20 }; };
template < int index >
struct index_propertie s
{ enum { level = __index_propert ies__<index,0>: :level }; };

Dec 12 '06 #1
6 2937
On Dec 12, 11:31 pm, "Andre Kempe" <AKe...@the-map.dewrote:
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_propertie s<unsigned int>,
i get a compiler-error, complaining about the template-recursion of
__index_propert ies__. when i add a partially specialized template (the
three commented lines) to stop the template-recursion, it works.

does anyone how to make it work without this partial specialization? ??

my compiler is microsoft visual studio 2005

thanks in advance
andre

=============== =============== ========
template < unsigned int power , int base >
struct nth_power
{ enum { value = nth_power<power-1,base>::value* base }; };

template < int base >
struct nth_power< 0 , base >
{ enum { value = 1 }; };

template< unsigned int level >
struct level_propertie s {
enum { entries_in_laye r = nth_power<level ,2>::value };
enum { number_entries = nth_power<level +1,2>::value-1 };
enum { index_first_ele ment = number_entries - entries_in_laye r };

};template< int index , int level >
struct __index_propert ies__ {
typedef level_propertie s<levelthis_lev el;
enum { level = (this_level::nu mber_entries>in dex)? level :
__index_propert ies__<index,lev el+1>::level };
};

// template< int index >
// struct __index_propert ies__<index,20>
// { enum { level = 20 }; };

template < int index >
struct index_propertie s
{ enum { level = __index_propert ies__<index,0>: :level }; };
I'm not claiming to fully understand you code but it seems to me like
you are trying to use recursion to determine the level_propertie s. When
using recursion you must have a base-case somewhere or you'll end up
recursing(?) forever. Is there something wrong with the partial
specialization?

--
Erik Wikström

Dec 13 '06 #2
er****@student. chalmers.se schrieb:
>
I'm not claiming to fully understand you code but it seems to me like
you are trying to use recursion to determine the level_propertie s. When
using recursion you must have a base-case somewhere or you'll end up
recursing(?) forever. Is there something wrong with the partial
specialization?

--
Erik Wikström
heij.

well, i simply do not consider the partial specialization a very
elegant solution, as it restricts the maximum recursion level to some
artificial value that has nothing to do with the compiler in use or the
problem being solved.

and as i remember, template should not be evaluated when it is not
used. therefore i thought that the ? would be enough to stop an endless
template-recursion.

andre

Dec 13 '06 #3

Andre Kempe napsal:
er****@student. chalmers.se schrieb:

I'm not claiming to fully understand you code but it seems to me like
you are trying to use recursion to determine the level_propertie s. When
using recursion you must have a base-case somewhere or you'll end up
recursing(?) forever. Is there something wrong with the partial
specialization?

--
Erik Wikström

heij.

well, i simply do not consider the partial specialization a very
elegant solution, as it restricts the maximum recursion level to some
artificial value that has nothing to do with the compiler in use or the
problem being solved.

and as i remember, template should not be evaluated when it is not
used. therefore i thought that the ? would be enough to stop an endless
template-recursion.

andre
Well, for recursion (either function recursion or template recursion)
you need some condition, which ends the recursion. For templates is
such condition usualy made with partial specialization (or with full
specialization) .

You mentioned, that only templates, which are instantiated, are used.
That's right. But you need infinite number of templates, because
__index_propert ies__<index, levelis dependent on
__index_propert ies__<index, level + 1>. So if you declare

index_propertie s<2iprop;

You need __index_propert ies__<2,0>::lev el. That depends on
__index_propert ies__<2,1>::lev el, which depends on
__index_propert ies__<2,2>::lev el, depends on
__index_propert ies__<2,3>::lev el .... etc.

You definitely need to pass limit to index_propertie s. It may be
optional parameter, something like

template < int index, int limit = 100>
struct index_propertie s
{
enum { level = __index_propert ies__<index,0, limit>::level };
};

And then write partial specialization of __index_propert ies__:
template< int index, int LEVEL >
struct __index_propert ies__<index,LEV EL, LEVEL>
{ enum { level = LEVEL };
};

Even better solution, which does not need to add new parameter to
__index_propert ies__ is to rewrite __index_propert ies__ to start with
given limit and make it dependent on it's predecessor. Than write
specialization for value 0.

Dec 13 '06 #4

Ondra Holub schrieb:
>
Well, for recursion (either function recursion or template recursion)
you need some condition, which ends the recursion. For templates is
such condition usualy made with partial specialization (or with full
specialization) .

You mentioned, that only templates, which are instantiated, are used.
That's right. But you need infinite number of templates, because
__index_propert ies__<index, levelis dependent on
__index_propert ies__<index, level + 1>. So if you declare

index_propertie s<2iprop;

You need __index_propert ies__<2,0>::lev el. That depends on
__index_propert ies__<2,1>::lev el, which depends on
__index_propert ies__<2,2>::lev el, depends on
__index_propert ies__<2,3>::lev el .... etc.

You definitely need to pass limit to index_propertie s. It may be
optional parameter, something like

template < int index, int limit = 100>
struct index_propertie s
{
enum { level = __index_propert ies__<index,0, limit>::level };
};

And then write partial specialization of __index_propert ies__:
template< int index, int LEVEL >
struct __index_propert ies__<index,LEV EL, LEVEL>
{ enum { level = LEVEL };
};

Even better solution, which does not need to add new parameter to
__index_propert ies__ is to rewrite __index_propert ies__ to start with
given limit and make it dependent on it's predecessor. Than write
specialization for value 0.
jepps, this is exactly what i've been trying to avoid, making any
asumptions on the limit. because the template is not recursed
uncondintionall y, but only when the limit has not been reached yet, i
thought that this is enough to stop recursion.

ok, thanks to eveyone. i'll go and see what i can do.
andre

Dec 13 '06 #5
Andre Kempe wrote:
template < unsigned int power , int base >
struct nth_power
{ enum { value = nth_power<power-1,base>::value* base }; };

template < int base >
struct nth_power< 0 , base >
{ enum { value = 1 }; };

template< unsigned int level >
struct level_propertie s {
enum { entries_in_laye r = nth_power<level ,2>::value };
enum { number_entries = nth_power<level +1,2>::value-1 };
enum { index_first_ele ment = number_entries - entries_in_laye r };
};

template< int index , int level >
struct __index_propert ies__ {
typedef level_propertie s<levelthis_lev el;
enum { level = (this_level::nu mber_entries>in dex)? level :
__index_propert ies__<index,lev el+1>::level };
};

// template< int index >
// struct __index_propert ies__<index,20>
// { enum { level = 20 }; };
template < int index >
struct index_propertie s
{ enum { level = __index_propert ies__<index,0>: :level }; };
What about:

template < unsigned int power , int base >
struct nth_power
{ enum { value = nth_power<power-1,base>::value* base }; };

template < int base >
struct nth_power< 0 , base >
{ enum { value = 1 }; };

template< unsigned int level >
struct level_propertie s {
enum { entries_in_laye r = nth_power<level ,2>::value };
enum { number_entries = nth_power<level +1,2>::value-1 };
enum { index_first_ele ment = number_entries - entries_in_laye r };
};
template < bool condition, typename S, typename T >
struct conditional;

template < typename S, typename T >
struct conditional<tru e,S,T{

typedef S value;

};

template < typename S, typename T >
struct conditional<fal se,S,T{

typedef T value;

};

template< int index , int the_level >
struct __index_propert ies__ {
typedef level_propertie s<the_levelthis _level;
struct dummy {
enum { level = the_level };
};
enum { level
=
conditional< ( this_level::num ber_entries index ),
dummy, __index_propert ies__<index,the _level+1::value ::level };
};
// template< int index >
// struct __index_propert ies__<index,20>
// { enum { level = 20 }; };

#include <iostream>

template < int index >
struct index_propertie s
{ enum { level = __index_propert ies__<index,0>: :level }; };
int main ( void ) {
std::cout << index_propertie s< 15 >::level << '\n';
}
Best

Kai-Uwe Bux
Dec 13 '06 #6
Kai-Uwe Bux wrote:
Andre Kempe wrote:
>template < unsigned int power , int base >
struct nth_power
{ enum { value = nth_power<power-1,base>::value* base }; };

template < int base >
struct nth_power< 0 , base >
{ enum { value = 1 }; };

template< unsigned int level >
struct level_propertie s {
enum { entries_in_laye r = nth_power<level ,2>::value };
enum { number_entries = nth_power<level +1,2>::value-1 };
enum { index_first_ele ment = number_entries - entries_in_laye r };
};

template< int index , int level >
struct __index_propert ies__ {
typedef level_propertie s<levelthis_lev el;
enum { level = (this_level::nu mber_entries>in dex)? level :
__index_proper ties__<index,le vel+1>::level };
};

// template< int index >
// struct __index_propert ies__<index,20>
// { enum { level = 20 }; };
template < int index >
struct index_propertie s
{ enum { level = __index_propert ies__<index,0>: :level }; };

What about:

template < unsigned int power , int base >
struct nth_power
{ enum { value = nth_power<power-1,base>::value* base }; };

template < int base >
struct nth_power< 0 , base >
{ enum { value = 1 }; };

template< unsigned int level >
struct level_propertie s {
enum { entries_in_laye r = nth_power<level ,2>::value };
enum { number_entries = nth_power<level +1,2>::value-1 };
enum { index_first_ele ment = number_entries - entries_in_laye r };
};
template < bool condition, typename S, typename T >
struct conditional;

template < typename S, typename T >
struct conditional<tru e,S,T{

typedef S value;

};

template < typename S, typename T >
struct conditional<fal se,S,T{

typedef T value;

};

template< int index , int the_level >
struct __index_propert ies__ {
I forgot to mention this: names that contain "__" are reserved. So this code
has undefined behavior.
typedef level_propertie s<the_levelthis _level;
struct dummy {
enum { level = the_level };
};
enum { level
=
conditional< ( this_level::num ber_entries index ),
dummy, __index_propert ies__<index,the _level+1::value ::level };
};
// template< int index >
// struct __index_propert ies__<index,20>
// { enum { level = 20 }; };

#include <iostream>

template < int index >
struct index_propertie s
{ enum { level = __index_propert ies__<index,0>: :level }; };
int main ( void ) {
std::cout << index_propertie s< 15 >::level << '\n';
}
Best

Kai-Uwe Bux

Dec 13 '06 #7

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

Similar topics

4
2221
by: Ingo Nolden | last post by:
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
21
2105
by: Protoman | last post by:
I've been looking at template metaprogramming. It seems really cool, make the compiler do most of the work. I have very simple program that uses TMP,it calculates the square of a number, but it doesn't seem to work. Here it is: #include <iostream> #include <cstdlib> using namespace std; template<int n>
3
2702
by: shaun roe | last post by:
I have a document about 4 levels deep and in my XSLT I want to generate a unique string ID for each basic element based on its path through the hierarchy. If I use recursion, I am continually accessing the root element ID, here is a typical call: <xsl:variable name="fullPath" select="concat('p',../../../@id,'_c',../../@id,'_r',../@id,'_s',$slaveID) "/>
6
1831
by: Neal | last post by:
Hi All, I used an article on XSLT and XML and creating a TOC written on the MSDN CodeCorner. ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/dncodecorn/html/corner042699.htm However, it did'nt quite answer all my questions. How would one create a 3 level TOC when each item level / node was differently named (They used Template match and for-each, but the template match worked as on a 3 level structure they usedf the same named xml...
1
1636
by: will | last post by:
All Hope you can help with the following.. I am using recursion to calculate the sum of DEBT_INPUT_VALUE_BEFORE_SPLIT * CTXR_TAX_RATE elements, along the lines of sum(a*b) ie
2
1896
by: Dom Jackson | last post by:
Hello - I have a problem where I need to test some numeric code using a variety of built-in integer types: obj_type1 = obj_type2 OP obj_type3; // is obj_type1 correct? If I test with 10 built-in integer types, then I get 1000 permutations of the above statement. If I then test a dozen different operators, I get over 10,000 test operations.
4
1903
by: Alan Woodland | last post by:
I've been trying out more template metaprogramming ideas with typelists (mostly for personal learning, I'm aware boost most probably provides this facility already), and I've run into this small problem here. Comeau online (without C++0x, in strict mode) accepts this example pasted here, (apologies for the length of it). Unfortunately G++ (3.4, 4.1, 4.2) doesn't, and complains about index_find being private. The exact error it gives is:...
7
2986
by: er | last post by:
hi, could someone please help with this code? template<unsigned int N,unsigned int M> class A{ public: A(); };
20
3000
by: athar.mirchi | last post by:
..plz define it.
0
9586
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9423
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10043
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
9990
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
8869
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7406
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
5298
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
3956
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
2
3561
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.