473,387 Members | 1,606 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

'recursive' template problem

Hi,

I have a little problem to design some template classes in a realizable way.
I have some Container classes and some Proxy classes (proxies for
elements). Looks like this:

// P is the Proxy class.
template <typename T, typename P>
class Container
{
P
whatever() { return P(); }
};

template <typename T>
class Proxy1 { ... };

template <typename T>
class Proxy2 { ... };

For some reason every instance of class Proxy needs to know, which Container
class it is used for. Some behavior of Proxy is dependend on the specific
Container. So, when I call method whatever() I want to give the information
that I'm inside Container<T, P> to P. But I cannot give the Proxy class the
information via another template parameter, cause I would end up in an
endless recursive definition, since Container is parameterized by the
Proxy. Got my problem?

Best regards,
alex
Jul 22 '05 #1
11 2478
Alexander Stippler wrote:
For some reason every instance of class Proxy needs to know, which Container
class it is used for. Some behavior of Proxy is dependend on the specific
Container. So, when I call method whatever() I want to give the information
that I'm inside Container<T, P> to P. But I cannot give the Proxy class the
information via another template parameter, cause I would end up in an
endless recursive definition, since Container is parameterized by the
Proxy. Got my problem?


What's wrong with:
template <typename T, template <typename> class P>
class Container
{
typedef Container<T,P> Self;
P<Self>
etc
?
Just because you cannot write the type as a single expression does not
mean it is not a valid type.
Jul 22 '05 #2
Marc wrote:
What's wrong with:
template <typename T, template <typename> class P>
class Container
{
typedef Container<T,P> Self;
P<Self>
etc
?
Just because you cannot write the type as a single expression does not
mean it is not a valid type.


Thanks. Looks simple and correct. But I guess a default value for P is not
realizable this way, is it?

regards,
alex
Jul 22 '05 #3
Alexander Stippler wrote:
Marc wrote:
What's wrong with:
template <typename T, template <typename> class P>
class Container
{
typedef Container<T,P> Self;
P<Self>
etc
?
Just because you cannot write the type as a single expression does not
mean it is not a valid type.


Thanks. Looks simple and correct. But I guess a default value for P is not
realizable this way, is it?

regards,
alex


I get some doubts. How do I instantiate such a class?

Container<double, Proxy<Container<double, ....
Jul 22 '05 #4
Alexander Stippler wrote:
Alexander Stippler wrote:

Marc wrote:

What's wrong with:
template <typename T, template <typename> class P>
class Container
{
typedef Container<T,P> Self;
P<Self>
etc
?
Just because you cannot write the type as a single expression does not
mean it is not a valid type.


Thanks. Looks simple and correct. But I guess a default value for P is not
realizable this way, is it?

regards,
alex

I get some doubts. How do I instantiate such a class?

Container<double, Proxy<Container<double, ....


You probably need some way to terminate the instantiation loop:

Container<double, Proxy<Container<double, NullProxy<void> > > ...

Take a look at TypeList template idiom. The latest CUJ also has
a good article by V.Myrnyy that uses a similar pattern.

Victor
Jul 22 '05 #5
On Fri, 16 Jul 2004 18:19:14 +0200, Alexander Stippler
<st**@mathematik.uni-ulm.de> wrote:
Alexander Stippler wrote:
Marc wrote:
What's wrong with:
template <typename T, template <typename> class P>
class Container
{
typedef Container<T,P> Self;
P<Self>
etc
?
Just because you cannot write the type as a single expression does not
mean it is not a valid type.


Thanks. Looks simple and correct. But I guess a default value for P is not
realizable this way, is it?

regards,
alex


I get some doubts. How do I instantiate such a class?

Container<double, Proxy<Container<double, ....


Container<double, Proxy>

Tom
Jul 22 '05 #6
"Alexander Stippler" <st**@mathematik.uni-ulm.de> wrote...
OK, I will try to formulate my problem more concrete. Perhaps this helps.
Given:

template <typename T>
class Proxy { ... };

template <typename T, typename P = DefaultProxy<T> >
class OneContainerType
{
public:
P
operator()(int pos)
{
return P(int);
}
};

template <typename T, typename P = AnotherDefaultProxy<T> >
class AnotherContainerType
{
...
Supposedly the same as in 'OneContainerType', right?
};

Now I have to pass the information, which Container type called
operator(),
You mean, which Container type initialised the P.
since the implementation calls a template function
specialized for each different Container type. But how?
I do not want to provide an additional parameter for the Proxy
constructor (due to efficiency).
Any suggestions?


How about this: you create a templatised 'construct' member function
in your proxy and use that instead of the constructor?

template<class T> class DefaultProxy {
...

DefaultProxy(T t); // normal constructor

template<class C> DefaultProxy construct(T t) {
DefaultProxy dp(t);
// use the 'C' here as you want
...
return dp;
}
};

template <typename T, typename P = DefaultProxy<T> >
class OneContainerType {
P operator()(int pos) {
return P::construct<OneContainerType>(pos);
}
};

(you may need to put the keyword 'template' somewhere here, I am not
sure)

I know, it may not be the solution you seek, but given the information
you provided, I could only come up with this half-assed scheme...

Good luck!

Victor
Jul 22 '05 #7
Victor Bazarov wrote:
How about this: you create a templatised 'construct' member function
in your proxy and use that instead of the constructor?


I will try this. Sounds very good (and too simple not to get it on my
own :-(( ).
Thanks a lot for your help. I was really frustrated already.

Best regards,
Alex
Jul 22 '05 #8
Hi,

I was exulting to early. My problem wasn't formulated good enough. So your
proposal is adequate for the situation I described, but not for my problem.
Some more details:

Victor Bazarov wrote:

Now I have to pass the information, which Container type called
operator(),
You mean, which Container type initialised the P.


Not exactly. Initializing is not enough. The P object has to know
by which Container it was created for all its lifetime. Several member
functions need this information. Thus a templatized constructor is not
enough.
I know, it may not be the solution you seek, but given the information
you provided, I could only come up with this half-assed scheme...


I was really unprecise. Sorry.

Hope you can help me again. This little thing is quite essential for my
application,

Best regards,
alex
Jul 22 '05 #9
On Mon, 19 Jul 2004 10:47:23 +0200, Alexander Stippler
<st**@mathematik.uni-ulm.de> wrote:
Hi,

I was exulting to early. My problem wasn't formulated good enough. So your
proposal is adequate for the situation I described, but not for my problem.
Some more details:

Victor Bazarov wrote:

Now I have to pass the information, which Container type called
operator(),


You mean, which Container type initialised the P.


Not exactly. Initializing is not enough. The P object has to know
by which Container it was created for all its lifetime. Several member
functions need this information. Thus a templatized constructor is not
enough.
I know, it may not be the solution you seek, but given the information
you provided, I could only come up with this half-assed scheme...


I was really unprecise. Sorry.

Hope you can help me again. This little thing is quite essential for my
application,


How about:

template <typename T, typename Container>
class Proxy
{
public:
Proxy(int pos){}
};

template <typename T, template <class T, class Container> class P>
class OneContainerType
{
public:
typedef P<T, OneContainerType> proxy_type;
proxy_type operator()(int pos)
{
return proxy_type(pos);
}
};

int main()
{
typedef OneContainerType<int, Proxy> container_type;
container_type container;
container_type::proxy_type proxy = container(10);
}

That uses a template template paramenter for the proxy.

Tom
Jul 22 '05 #10
tom_usenet wrote:
template <typename T, typename Container>
class Proxy
{
public:
Proxy(int pos){}
};

template <typename T, template <class T, class Container> class P>
class OneContainerType
{
public:
typedef P<T, OneContainerType> proxy_type;
proxy_type operator()(int pos)
{
return proxy_type(pos);
}
};

int main()
{
typedef OneContainerType<int, Proxy> container_type;
container_type container;
container_type::proxy_type proxy = container(10);
}


Interesting approach. If I am honest, I do not understand, why it works, but
the compiler says its fine (as soon as I remove the names from the template
template parameters).
Could you please give me an idea how the typedef works. You just say Proxy,
but how does the compiler know how to instatiate the template parameters of
the Proxy type? Now I know again I know nothing about templates :-<.

Best regards,
alex
Jul 22 '05 #11
On Mon, 19 Jul 2004 20:17:56 +0200, Alexander Stippler
<st**@mathematik.uni-ulm.de> wrote:
tom_usenet wrote:
template <typename T, typename Container>
class Proxy
{
public:
Proxy(int pos){}
};

template <typename T, template <class T, class Container> class P>
class OneContainerType
{
public:
typedef P<T, OneContainerType> proxy_type;
proxy_type operator()(int pos)
{
return proxy_type(pos);
}
};

int main()
{
typedef OneContainerType<int, Proxy> container_type;
container_type container;
container_type::proxy_type proxy = container(10);
}
Interesting approach. If I am honest, I do not understand, why it works, but
the compiler says its fine (as soon as I remove the names from the template
template parameters).


Whoops, the reuse of "T" is the error, but there is no need for the
names, except perhaps for code clarity (as with parameter names in
function prototypes).
Could you please give me an idea how the typedef works. You just say Proxy,
but how does the compiler know how to instatiate the template parameters of
the Proxy type? Now I know again I know nothing about templates :-<.


You can have a template parameter that takes a template.

template <typename T, template <class, class> class P>

That defines the P parameter as taking a template with two type
parameters. Proxy is such a template, so it can be passed in as the P
parameter. Then, inside the definition of OneContainerType, you can
use P as a template with two template type parameters, just like
Proxy:
typedef P<T, OneContainerType> proxy_type;

Then you can instantiate your container types with different proxy
templates, and then use the proxy_type typedef to access the proxy
type that is associated with that container.

Tom
Jul 22 '05 #12

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

Similar topics

2
by: SainTiss | last post by:
Hi, If you've got a template class with lots of methods, and then you've got a type which works with the template, except for one method... What you need to do there is specialize the...
7
by: Rolf Kemper | last post by:
Dear All, somehow I remember that such or similar question was discussed already somewhere. But I can't find it anymore. I have a template calling itself. As long it goes deeper into the...
6
by: Johan Bergman | last post by:
Hi, Maybe someone can help me with this one. The following describes a somewhat simplified version of my problem, but I think it will be sufficient. I want to use class factories (virtual...
7
by: Jon Slaughter | last post by:
#pragma once #include <vector> class empty_class { }; template <int _I, int _J, class _element, class _property> class RDES_T {
1
by: Jon Slaughter | last post by:
I've managed to put together a template class that basicaly creates a recursive tree that lets you easily specify the "base" class of that tree and and ending notes and lets you stop the recursive...
1
by: Paul Guz | last post by:
I've discovered a quirk of .Net System.Xml.Xsl.XSLTransfrom that doesn't seem to exist in the MSXML2 transformation. When calling a recursive template for the first time, don't pass a parameter...
5
by: Mark Stijnman | last post by:
I am trying to teach myself template metaprogramming and I have been trying to create lists of related types. I am however stuck when I want to make a template that gives me the last type in a...
10
by: AsheeG87 | last post by:
Hello Everyone! I have a linked list and am trying to include a recursive search. However, I am having trouble understanding how I would go about that. I don't quite understand a recursive...
2
by: aaragon | last post by:
Hi guys, Is there a way to return a functor from a recursive call that takes different paths? Let's say that I have a tree structure like: root | first child ---- nextSibling ----nextSibling...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
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,...
0
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,...
0
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...

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.