I l@ve RuBoard Previous Section Next Section

10.8 Visitor Generic Components Quick Facts

  • To implement the Acyclic Visitor, use BaseVisitor (as the strawman base class), Visitor, and Visitable:

    
    
    class BaseVisitor;
    
    
    
    
    
    template <class T, typename R = void>
    
    
    class Visitor;
    
    
    
    
    
    template
    
    
     <
    
    
       typename R = void,
    
    
       template<class, class> CatchAll = DefaultCatchAll
    
    
    >
    
    
    class BaseVisitable;
    
    
    
  • The first template parameter of Visitor and BaseVisitable is the return type of the Visit and Accept member functions, respectively. It defaults to void (this is the return type assumed in the GoF book examples and in most Visitor descriptions).

  • The second template parameter of BaseVisitable is the policy for handling the catch-all issue (see Section 10.2).

  • Derive the root of your hierarchy from BaseVisitable. Then use the macro DEFINE_VISITABLE() in each class in the hierarchy, or provide a handmade implementation of Accept(BaseVisitor&).

  • Derive your concrete Visitor classes from BaseVisitor. Also derive your concrete visitor from Visitor<T>, for each type T you are interested in visiting.

  • For the GoF Visitor, use the CyclicVisitor template:

    
    
    template <typename R, class TList>
    
    
    class CyclicVisitor;
    
    
    
  • Specify the types visited in the TList template argument.

  • Use CyclicVisitor with your code just as you would use a classic GoF visitor.

  • If you need to implement only part of a GoF Visitor (the nonstrict variant), derive your visitable hierarchy from BaseVisitorImpl. BaseVisitorImpl implements all the Visit overloads to call OnUnknownVisitor. You can override part of this behavior.

  • The OnUnknownVisitor static member function of the CatchAll policy provides a catch-all sink for Acyclic Visitor. If you use BaseVisitorImpl, it will provide a catch-all for the GoF Visitor, too. The stock implementation of OnUnknownVisitor returns a default-constructed value of the return type you chose. You can override this behavior by providing custom implementations of CatchAll.

    I l@ve RuBoard Previous Section Next Section