www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Alias in templates

reply Peer Sommerlund <peer.sommerlund gmail.com> writes:
Hi.

I'm trying to write a template for lists, using a slightly different approach
than normal. I think I have not quite understood how alias works.

Could somebody please explain why the following gives compiler errors? I'm
trying to use a member variable as a template parameter. (Forgive typos, this
is written from memory and my C++ background may shine through)

// This should be used as a member variable m in some class T
class ListLink(T, alias m) {
  T* next;
  T* prev;
  void insert_after(T* n) {
    n.m.next = next;
    n.m.prev = prev;
    next = n.m;
    n.m.next.prev = n.m;
  }
}

class MyNode {
  ListLink!(MyNode,allocated) allocated;
  int some_data;
}

Why do it this way?

The goal is to be able to write some structure like:

class MyAdvanceNode {
  ListLink!(MyAdvanceNode,allocated) allocated;
  ListLink!(MyAdvanceNode,neighbours) neighbours;
  string name;
  MapLink!(MyAdvanceNode,nameIndex,name) nameIndex;
  TreeLink!(MyAdvanceNode,topology) topology;
  // ... and lots of user data here
}

So I can erase a node using O(1) time, navigate between topology, and
neighbours, and back again.
Dec 13 2006
next sibling parent Don Clugston <dac nospam.com.au> writes:
Peer Sommerlund wrote:
 Hi.
 
 I'm trying to write a template for lists, using a slightly different approach
 than normal. I think I have not quite understood how alias works.
 
 Could somebody please explain why the following gives compiler errors?

Because an alias parameter is passed as a fully-qualified name. So in this case:
 module foo;
 class MyAdvanceNode {
   ListLink!(MyAdvanceNode,allocated) allocated;

'm' is not 'allocated', but rather 'foo.MyAdvanceNode.allocated'. So 'n.m.next' is not going to make any sense. You _might_ be able do this as a mixin instead, with a syntax something like: class MyAdvanceNode { mixin ListLink!(MyAdvanceNode) allocated; } -- but you'll have to develop a few new tricks, I think.
Dec 14 2006
prev sibling parent "John Reimer" <terminal.node gmail.com> writes:
On Wed, 13 Dec 2006 23:39:07 -0800, Peer Sommerlund  =

<peer.sommerlund gmail.com> wrote:

 Hi.

 I'm trying to write a template for lists, using a slightly different  =

 approach
 than normal. I think I have not quite understood how alias works.

 Could somebody please explain why the following gives compiler errors?=

 I'm
 trying to use a member variable as a template parameter. (Forgive typo=

 this
 is written from memory and my C++ background may shine through)

 // This should be used as a member variable m in some class T
 class ListLink(T, alias m) {
   T* next;
   T* prev;
   void insert_after(T* n) {
     n.m.next =3D next;
     n.m.prev =3D prev;
     next =3D n.m;
     n.m.next.prev =3D n.m;
   }
 }

 class MyNode {
   ListLink!(MyNode,allocated) allocated;
   int some_data;
 }

 Why do it this way?

 The goal is to be able to write some structure like:

 class MyAdvanceNode {
   ListLink!(MyAdvanceNode,allocated) allocated;
   ListLink!(MyAdvanceNode,neighbours) neighbours;
   string name;
   MapLink!(MyAdvanceNode,nameIndex,name) nameIndex;
   TreeLink!(MyAdvanceNode,topology) topology;
   // ... and lots of user data here
 }

 So I can erase a node using O(1) time, navigate between topology, and
 neighbours, and back again.

In addition to Don's comments about allocation: I don't believe "prev" and "next" should be pointers in this case. The = = class types are references, so the result is a pointer to a reference, = which I don't think is the intention. This means "n.m.next =3D next" me= rely = assigns class pointers. Using the reference alone may be adequate. -JJR
Dec 14 2006