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); }