Listing 3

(a)
class Link
{
protected:
  virtual void *v_traverse(void *) = 0;
public:
  virtual Link *clone(void) const = 0;
  virtual size_t get_size(void) const { return 1; }
};
template<class Src, class Dst>
class Typed_Link : public Link
{
protected:
  void *v_traverse(void *src)
  { 
    return (void *)&traverse(*(Src *)src);
  }
public:
  Dst &traverse(Src &) = 0;
};


(b)
template<class Src, class Dst>
class Chain : private std::list<Link *>, public Typed_Link<Src, Dst>
{
public:
  // special constructors
  template<class Mid>
  Chain(const Typed_Link<Src,Mid> &a, const Typed_Link<Mid,Dst> &b);
  // etc.
  size_t get_size(void) const
  {
    size_t ret = 0;
    for (const_iterator i = begin(); i != end(); ++i) {
      ret += (*i)->get_size();
    }
    return ret;
  }
  Dst &traverse(Src &s)
  {
    void *tmp = &s;
    iterator i;
    try {
      for (i = begin(); i != end(); ++i) {
    tmp = (*i)->v_traverse(tmp);
      }
    } 
    // (exception handlers here)
    // ...
    return *(Dst *)tmp;
  }
};
// spc: this simplifies the object definitions
template<class Src, class Mid, class Dst>
class Chain<Src, Dst>
operator+(const Typed_Link<Src, Mid> &a, 
         const Typed_Link<Mid, Dst> &b)
{
  return Chain<Src, Dst>(a, b);
}