Merge Two Queues

    ...
class Cell
{
friend class Queue;
public:
   Cell(void *ptr, Cell *lst)
   {
      item = ptr;
      next = lst;
      copyof = NULL;
   }
   Cell(void *ptr, Cell *lst, void *(* cpfn)(void *))
   {
      item = ptr;
      next = lst;
      copyof = cpfn;
   }
   void *copyon() { return copyof(item); }
private:
   void *item;
   Cell *next;
   void *(* copyof)(void *);
};

class Queue
{
public:
   Queue(void (* d)(void *)) { dispfn = d; head = NULL; tail = NULL; }
   Queue() { dispfn = intdisplay; cpfn = copyof; head = NULL; tail = NULL; }
   void  enqueue(void *t)
   {
      Cell *ptr;
      if (t == NULL) return;
      Cell *h = new Cell(t, NULL, cpfn);
      if (head == NULL)
         head = h;
      else
         tail->next = h;
      tail = h;
   }
   void *dequeue()
   {
      if (head == NULL) return NULL;
      void *ptr = head;
      void *t = head->item;
      head = head->next;
      delete ptr;
      if (head == NULL) tail = NULL;
      return t;
   }
   Queue *mult(int n);
   Cell  *header() { return head; }
   Queue *merge(Queue *q);
   void display()
   {
     if (head == NULL) { printf("(empty)\n");  return; }
     for (Cell *t=head ; t != NULL ; t=t->next) (dispfn)(t->item);
     printf("\n");
   }
   int   empty()  {  return head == NULL;  }
private:
   Cell *head;
   Cell *tail;
   void (* dispfn)(void *);
   void *(* cpfn)(void *);
};

int cmpfunc(void *a, void *b)
{
   if (*(int *)a < *(int *)b) return -1;
   else
   if (*(int *)a > *(int *)b) return 1;
   else
      return 0;
}

Queue *Queue::mult(int n)
{
   for (Cell *h = head ; h != NULL ; h = h->next) *(int *)h->item *= n;
   return this;
}

Queue *Queue::merge(Queue *q)
{
   Cell *r = q->header();
   Cell *s = head;
   Cell *h = NULL;
   Cell *p = NULL;
   while (s != NULL || r != NULL)
   {
      if ((s == NULL && r != NULL) ||
          (s != NULL && r != NULL && cmpfunc(r->item,s->item) < 0))
      {
         void *t = r->copyon();
         if (h == NULL) h = p = new Cell(t, NULL, r->copyof);
         else
         {
            p->next = new Cell(t, NULL, r->copyof);
            p = p->next;
         }
         r = r->next;
      }
      else
      if ((r == NULL && s != NULL) ||
          (s != NULL && r != NULL && cmpfunc(r->item,s->item) >= 0))
      {
         if (h == NULL) h = p = s;
         else
         {
            p->next = s;
            p = p->next;
         }
         s = s->next;
      }
   }
   head = h;
   tail = p;
   return this;
}

int main()
{
   Queue *s = new Queue();
   Queue *r = new Queue();
   s->enqueue(new int(4));
   s->enqueue(new int(9));
   s->enqueue(new int(13));
   s->enqueue(new int(16));
   s->enqueue(new int(21));
   s->display();
   r->enqueue(new int(1));
   r->enqueue(new int(5));
   r->enqueue(new int(17));
   r->enqueue(new int(18));
   r->enqueue(new int(25));
   r->display();
   s->merge(r);
   s->display();
   r->display();
   s->mult(6);
   s->display();
   return 1;
}