Self refrence to class type in template

G

Greg Phillips

Hello everyone,

I have read the section on templates in The C++ Programming Language 3rd
edition 3
times over the last 4 days. Still I am stumped. I'll explain a bit about
what I am doing
before asking the question so as you can understand what I am trying to
accomplish.
Any help would be much appreciated.

Lets say we are implementing a message sorting system where the messages are
strings in
the form of:
TAG message...

This can be encapsulated so message could be a form of TAG message also. So
you could
have a message like TAG TAG TAG message, where each tag would be aimed at a
system
further down the line (somewhat like UUCP).

My first run at this went something like:

class bqueue {
private:
typedef std::map<std::string, baueue*> queue_table;
typedef std::map<std::string> queue;
static queue_table msg_table;
static bqueue* default_queue;
queue msg_queue;
static int push(std::string message, bqueue& imsg_queue);
public:
// automatic constructor
~bqueue(); // call unregsister_queue(*this);
static int register_default_aueue(bqueue& registering_queue);
static int register_queue(std::string message, bqueue&
registering_queue);
static int unregister_queue(bqueue& unregistering_queue);
static int sort_queue(std::string message);
std::string pop();
bool queued_messages();
};

This being the class where messages comming into the system would go. If an
object needed
messages that had a TAG no deeper than the first level they could:

bqueue object1;
object1.register_queue("TAG1", object1);
object1.register_queue("TAG2", object1);
.....
if(object1.queued_messages())
message = object1.pop();

The second, third, forth, ...., level messages could be handled by a class
almost exactly the same
except it would have a bool to mark one instantiation master and a way to
register messages with
the queue right before it in the stream.

That is the basics of what I am doing. Here is where the problem is and
where I am stumped.
Because the class refrences itself as a type to be able to access
instantiations of itself to be able to
push messages on the proper queues, and because it relys on the nature of
static variables and static
functions to do it's work, diriving the second class from the first wouldn't
make much sense since the
static functions that refrence itself would need rewrote. You would end up
with two copies of almost
identical code to maintain. Also it would be nice to be able to declare a
generic_queue as to be able to
create down stream routing systems if need be.

This class works great as a concreate class but there is one major problem
in defining it as a template:

template<class T> class generic_queue { .... }; // where T replaces all the
self refrences

generic_queue<my_queue> my_queue; // error

I need to to know figure out how to define a template class that refrences
itself, and that the refrences to
itself is the generic type. That way it would be possible to declare
diffrent class types with the same
functionality, hence seprate message queueing systems.

Like I said, any help would be much appreciated.
 
V

Victor Bazarov

Greg said:
[...]
Lets say we are implementing a message sorting system where the messages are
strings in
the form of:
TAG message...

This can be encapsulated so message could be a form of TAG message also. So
you could
have a message like TAG TAG TAG message, where each tag would be aimed at a
system
further down the line (somewhat like UUCP).

My first run at this went something like:

class bqueue {
private:
typedef std::map<std::string, baueue*> queue_table;

typedef std::map said:
typedef std::map<std::string> queue;

That is impossible. std::map<> requires at least two arguments.

Perhaps you meant

typedef std::queue<std::string> queue;

?
static queue_table msg_table;
static bqueue* default_queue;
queue msg_queue;
?

static int push(std::string message, bqueue& imsg_queue);
public:
// automatic constructor
~bqueue(); // call unregsister_queue(*this);
static int register_default_aueue(bqueue& registering_queue);
static int register_queue(std::string message, bqueue&
registering_queue);
static int unregister_queue(bqueue& unregistering_queue);
static int sort_queue(std::string message);
std::string pop();
bool queued_messages();
};

This being the class where messages comming into the system would go. If an
object needed
messages that had a TAG no deeper than the first level they could:

bqueue object1;
object1.register_queue("TAG1", object1);
object1.register_queue("TAG2", object1);
....
if(object1.queued_messages())
message = object1.pop();

The second, third, forth, ...., level messages could be handled by a class
almost exactly the same
except it would have a bool to mark one instantiation master and a way to
register messages with
the queue right before it in the stream.

That is the basics of what I am doing. Here is where the problem is and
where I am stumped.
Because the class refrences itself as a type to be able to access
instantiations of itself to be able to
push messages on the proper queues, and because it relys on the nature of
static variables and static
functions to do it's work, diriving the second class from the first wouldn't
make much sense since the
static functions that refrence itself would need rewrote. You would end up
with two copies of almost
identical code to maintain. Also it would be nice to be able to declare a
generic_queue as to be able to
create down stream routing systems if need be.

This class works great as a concreate class but there is one major problem
in defining it as a template:

template<class T> class generic_queue { .... }; // where T replaces all the
self refrences

generic_queue<my_queue> my_queue; // error

What error? What is the first 'my_queue'? Is that a type? Why
do you call the object the same? Did you mean to instantiate your
queue somehow differently, like

generic_queue my_queue(my_queue);

? I am not sure I see the point in that, but it's possible.
I need to to know figure out how to define a template class that refrences
itself, and that the refrences to
itself is the generic type. That way it would be possible to declare
diffrent class types with the same
functionality, hence seprate message queueing systems.

Like I said, any help would be much appreciated.

If you need to define a list of lists, it's possible, just write

std::list<std::list<std::list< ...

but you have to stop and make it concrete at some point, like

std::list<std::list<std::list<std::list<int> > > > blah;

The same with your stuff. There cannot be infinite depth of self-
reference in your type definition, but if you template is generic
enough and complies to the requirements it sets for its argument,
then what to stop you to make it self-contained?

As you probably guessed by now, I am not certain I understand what
you are asking. Self-referencing classes are all over the place,
a linked list is the simplest example. Self-referencing objects
can also exist, a circular queue of one element is something that
might be seen as one. Some stuff is handled in the implementation
and some is inherent to the class itself, like the ability to have
a list of lists comes from the fact that list itself complies with
the requirements list imposes on its contained object...

I believe more information is in order.

Victor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top