By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,144 Members | 1,250 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,144 IT Pros & Developers. It's quick & easy.

'recursive' template problem

P: n/a
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
Share this Question
Share on Google+
11 Replies


P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
"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

P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
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 discussion thread is closed

Replies have been disabled for this discussion.