   C++ templates
  Prompted by another thread where someone was asking about double linked lists, as an exercise I made my own implementation based on inheritance from a List class. In order to avoid typecasts when accessing next and prev I templated it, a first for me.Now, I know there are some things I do which are horribly unsafe, but specifically with regard to the templating... is it stupid?The thing is, I can think of a number of situations where I might want to do something similar to avoid numerous typecasts when using inheritance (there are some typecasts in the List class, but at least not outside it).#include <iostream>using namespace std;#define forAll(T,i,l) for(T* i = l->next; i != l; i = i->next)template<class T> class List{ public:  T* next;  T* prev;  List() { glue((T*)this); };  ~List() {};  void glue(T* n) { next = n; n->prev = (T*)this; };  void remove() { prev->glue(next); };  void del() { remove(); delete this; };  void add(T* n) { prev->glue(n); n->glue((T*)this); };  void merge(List* l) { prev->glue(l->next); l->prev->glue((T*)this); };  bool isEmpty() { return next == this; };  void purge() { while (!isEmpty()) next->del(); }   int size() { int count = 0; forAll(T,i,this) ++count; return count; };};class MyClass : public List<MyClass>{ public:  int myData;  MyClass(int data) { myData = data; };};int main(int argc, char** argv){  // Create 2 lists  List<MyClass>* list1 = new List<MyClass>();  List<MyClass>* list2 = new List<MyClass>();  // Add a node to each  list1->add(new MyClass(1));  list2->add(new MyClass(2));  // Merge lists  list1->merge(list2);  delete list2;  // Traverse list and output data  forAll(MyClass,i,list1) cout << i->myData << endl;  // Delete nodes  list1->purge();  // Delete the list  delete list1;  // Done  system("PAUSE");}
  This is C++, you should rename the next and prev fields, make them private, and put in public next() and prev() functions, it makes it much harder to mess up by mistake.Finally, since you are making a templated doubly linked list, you really should be using std::list, unless you have a very good performance reason for nodes to be their own iterator (and even then, I have used a wrapper class to support this with a std::list).   ;  He said as an excersize.And yes it's horribly unsafe, and a horrible design, but the templating is sound.I would suggest looking at the STL to see how they do what they do. The iterator concept simplifies things inordinately.   ;  Also, instead of using your forAll macro, consider using std::for_each.   ;  Yeah, the design is awful. The templating is sound, but you want the user of the list to not have to worry about inheritance. And you *definitely* don't want the user to be thinking about node objects - just list objects. You could add an extra level of wrapping (I think this will work):template <typename T>class ListNode;template <typename T>class ListNodeBase {  ListNode<T> * prev, next;  // everything else basically as before};template <typename T>class ListNode : public ListNodeBase<T> {  T data;  ListNode(const T& data) : data(data) {}};My compiler's std::list implementation does not template the base class, which apparently reduces code duplication at the expense of some static_casting (according to the comments). Personally I would probably not do the inheritance at all if I were implementing it, at least until I saw a good reason to. I.e.template <typename T>class ListNode {  ListNode<T> * prev, next;  T data;  // other stuff - maybe I'd run into a problem?};Also, you should strongly consider making a separate list object which simply holds a pointer to the first node. That also gives you a good place to store list statistics, such as a cache of the length of the list.Common std::list implementations make use of a number of interesting tricks, actually, which many people might not think of. My implementation for example actually stores a circular linked list, and remembers which node is the front - this seems to be in order to make it easier to implement iterators (forward and reverse).   ;  I think there is a slight misunderstanding... the data placed in the list in my example isn't myData, it is MyClass. I'm not doing a list of integers, but a list of class instances.Anyway, thanks for the comments.As for the for_each method, it seems to require that I replace "i = i->next" with "i plus plus". I can't quite get my mind to wrap around the syntax required for the operator overloading. Perhaps some kind soul could help me with that?   ;  I am confused why MyClass inherits from List<MyClass>.  Since each element in your list is of type MyClass, and since each MyClass is also a List<MyClass>, wouldn't that mean that each item in the list is also a list, which also is capable of containing items, each of which are also lists, et cetera?  Basically, you seem to have accidentally created a tree data structure, not a list.From my brief glance over the code, you should be perfectly capable of removing the inheritance; there doesn't seem to be any need or use for it.  It only serves to complicate things.[edit]Nevermind, I see you are using the List class as though it were a node, not a list.  I suppose this is common, and I probably did something similar back in the day, but I'm so used to std::list's interface that it totally throws me off every time I see it.If it's for a learning exercise, I would still encourage using std::list, if only to keep the same or similar interface.  You can still go through the work of writing the implementation details.[/edit]   