468,310 Members | 1,425 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,310 developers. It's quick & easy.

self referential template parameters?

This is mostly just another "gee it would be nice if it had X" post.

Recently I have come across two separate problems which both exhibit the
need for a way to self reference when instantiating a template.

Example #1: B-trees

While implementing a B-Tree I ended up with an (abbreviated) node structure
looking something like this:

template <class KeyType, class ChildType, int ORDER>
class BTreeNode {
public:
...
private:
KeyType key[ORDER-1];
ChildType child[ORDER];
};

for the assignment KeyType was a simple integer and the child type was an
offset into on-disk storage. While doing initial development I decided
what I would like to keep the tree entirely in memory (to make debugging a
bit simpler). This presents me with a problem. I need to use a template
to define itself (ChildType = BTreeNode<int,ChildType,32>). erk.

I resigned myself to the idea that this was just an unusual situation and
implemented a special BTreeSelfNode for use when in memory...a hack but it
kind of works.
Example #2: Functors (function objects)

A few weeks later I run across a situation where I need to handle function
pointers to member functions of a class. I think "functors" and begin
writing a fairly standard set of wrapper classes, looking something like
this:

class FunctorBase {
public:
virtual void callFunction();
};

template <class BaseType, class ParamType>
class Functor : public FunctorBase {
public:
Functor( BaseType &obj, BaseType::*mfp, ParamType param ):
m_obj(obj),m_mfp(mfp),m_param(param) {};
virtual void callFunction() {
m_obj::*m_mfp(m_param);
}
private:
...
};

And all was right and good (assuming I remember the code vaguely correctly
here)...until I wanted to pass the functor object in as the parameter
(ParamType = Functor<Foo,ParamType>).

Hmm....so in the last month I've found two separate reasons to need such a
self referential template, but I don't think there is a way to define it
that a compiler will accept. It would appear *possible* for the compiler
to generate a concise symbol name for such a thing (say: Functor<Foo,^13>
^13 == self reference to symbol name starting 13 characters previous), and
it would seem possible to come up with a non-conflicting syntax for the
compiler (maybe: Functor<Foo,<1> >, <1> == self ref, up one template level,
that would be fun to read :P ).

Maybe I'm just sick and twisted, but it seems like something that would be
worth having. Also, suggestions on how to implement these self referencing
templates would be appreciated, since I doubt this extension will ever make
it into my compiler.

Thanks for your time
-Scott Tillman aka SpeedBump
Jul 19 '05 #1
1 3315
"SpeedBump" <sp*******@speedbump.org> wrote in message
news:lE*********************@twister.southeast.rr. com...
[...]
template <class KeyType, class ChildType, int ORDER>
class BTreeNode {
public:
...
private:
KeyType key[ORDER-1];
ChildType child[ORDER];
};
[...]
I need to use a template
to define itself (ChildType = BTreeNode<int,ChildType,32>).
[...]


There is nothing stopping you from using a template class as
one of its own arguments. However, you can't create a recursive
class definition, because it has infinite size (imagine trying to
instantiate your example above). You could certainly store a
pointer to children of the same class, just like you can store a
pointer to a struct of the same type (which is necessary to
create a linked list node). However, you can't use the BTreeNode
as a ChildType, because BTreeNode is a template, and
ChildType is a non-template template argument. However, if
you really wanted to make a recursive node type, you could do
something like this:

struct BTreeNode
{
template <class KeyType, class ChildType, int ORDER>
class apply
{
typedef ChildType::apply<KeyType, ChildType, ORDER>
child_type;
private:
KeyType key[ORDER-1];
child_type* child[ORDER];
};
};

BTreeNode::apply<int, BTreeNode, 32> node;

I think this is easier with Boost.MPL.Lambda, but unfortunately,
I'm not fluent enough in that to speak it off the top of my head.
However, you should probably take a close look at MPL yourself.
Also, Google for Curiously Recurring Template Pattern or
Barton-Nackman.

Dave

---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.532 / Virus Database: 326 - Release Date: 10/27/2003
Jul 19 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

9 posts views Thread by Anthony Heading | last post: by
8 posts views Thread by Paul Roberts | last post: by
1 post views Thread by anarghya | last post: by
4 posts views Thread by aakbar | last post: by
1 post views Thread by bhavneet | last post: by
reply views Thread by NPC403 | last post: by
reply views Thread by Teichintx | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.