Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>From Modern C++ - Design Generic Programming and Design Patterns Applied - Andrei Alexandrescu</p> <pre><code>#include &lt;iostream&gt; class BaseVisitor { public: virtual ~BaseVisitor() {}; }; template &lt;class T, typename R = int&gt; class Visitor { public: virtual R visit(T &amp;) = 0; }; template &lt;typename R = int&gt; class BaseVisitable { public: typedef R ReturnType; virtual ~BaseVisitable() {}; virtual ReturnType accept(BaseVisitor &amp; ) { return ReturnType(0); } protected: template &lt;class T&gt; static ReturnType acceptVisitor(T &amp;visited, BaseVisitor &amp;visitor) { if (Visitor&lt;T&gt; *p = dynamic_cast&lt; Visitor&lt;T&gt; *&gt; (&amp;visitor)) { return p-&gt;visit(visited); } return ReturnType(-1); } #define VISITABLE() \ virtual ReturnType accept(BaseVisitor &amp;v) \ { return acceptVisitor(*this, v); } }; /** example of use */ class Visitable1 : public BaseVisitable&lt;int&gt; { /* Visitable accept one BaseVisitor */ public: VISITABLE(); }; class Visitable2 : public BaseVisitable&lt;int&gt; { /* Visitable accept one BaseVisitor */ public: VISITABLE(); }; class VisitorDerived : public BaseVisitor, public Visitor&lt;Visitable1, int&gt;, public Visitor&lt;Visitable2, int&gt; { public: int visit(Visitable1 &amp; c) { std::cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; std::endl; } int visit(Visitable2 &amp; c) { std::cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; std::endl; } }; int main(int argc, char **argv) { VisitorDerived visitor; Visitable1 visitable1; Visitable2 visitable2; visitable1.accept(visitor); visitable2.accept(visitor); } </code></pre> <p>Is possible to avoid dynamic_cast with CRTP pattern like:</p> <pre><code>#include &lt;iostream&gt; class BaseVisitor { public: virtual ~BaseVisitor() {}; }; template &lt;class T&gt; class Visitor { public: virtual void visit(T &amp;) = 0; }; template &lt;class Visitable&gt; class BaseVisitable { public: template &lt;typename T&gt; void accept(T &amp; visitor) { visitor.visit(static_cast&lt;Visitable &amp;&gt;(*this)); } }; /** example of use */ class Visitable1 : public BaseVisitable&lt;Visitable1&gt; { }; class Visitable2 : public BaseVisitable&lt;Visitable2&gt; { }; class VisitorDerived : public BaseVisitor, public Visitor&lt;Visitable1&gt;, public Visitor&lt;Visitable2&gt; { public: void visit(Visitable1 &amp; c) { std::cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; std::endl; } void visit(Visitable2 &amp; c) { std::cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; std::endl; } }; int main(int argc, char **argv) { VisitorDerived visitor; Visitable1 visitable1; Visitable2 visitable2; visitable1.accept&lt;VisitorDerived&gt;(visitor); visitable2.accept&lt;VisitorDerived&gt;(visitor); } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload