Boost logo

Boost :

From: Tanton Gibbs (thgibbs_at_[hidden])
Date: 2002-11-26 04:53:35

I have created a "Generic Visitor Class" using the MPL. I thought I would
submit it to the list to see if there is any interest in it. Basically, you
create an MPL list that contains each of the possible classes you can visit.
For example:

struct Base { virtual ~Base(){} };
struct Derived1 : public Base {};
struct Derived2 : public Base {};
struct Derived3 : public Derived1 {};

Visitor< boost::mpl::list< Base, Derived1, Derived2, Derived3 > > v;

Then, you call the visit method passing a pointer convertable to type Base
and a Function object.

struct Function {
  void operator()( Base* ) { cout << "BASE!" << endl; }
  void operator()( Derived1* ) { cout << "DERIVED1!" << endl; }

Base* d1 = new Derived1;

v.visit( d1, Function() );

This will print out DERIVED1!

A couple of notes:
The list does not have to be in any particular order, it will reorder the
list as needed.
Visitor class can take 4 template parameters:
  The first is the list of classes that can be visited
  The second is the base class to use - this is automatically found if not
  The third is a pointer policy - PointerPolicy<T>::type defaults to T*, but
this can be used
          to do references and shared_ptrs (implementations for both are
  The final policy is how to convert from T to B. if T is T*, then
dynamic_cast is used,
   if T is T&, then a try{} is put around the dynamic_cast. if T is
shared_ptr<T> then
   the shared_ptr mechanism for doing this is used. It can be specialized
as needed.
If the list contains diamond inheritance, then the base class must be
specified...the is_base_and_derived template won't handle this. Naturally,
if the diamond inheritance
uses virtual base classes, then the base class does NOT have to be

Attached is Visitor.h, Visitor_Smart_Pointer.h, and test.cpp.

Also, I have tested this on GCC 3.2.1 - I'm not sure how it will fare on
other compilers.

If there is any interest, or any suggestions, please let me know.


Boost list run by bdawes at, gregod at, cpdaniel at, john at