    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Defining Visitors Inline in Modern C++</title>
        <link>https://members.accu.org/index.php/journals/2021</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">Overload Journal #123 - October 2014 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c342/">o123</a>
                    (8)
<br />

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c65/">Programming</a>
                    (877)
<br />

                                            <a href="https://members.accu.org/index.php/journals/c342-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c342+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Defining Visitors Inline in Modern C++</h1>
<p><strong>Author:</strong>&nbsp;Martin Moene</p>
<p>
<strong>Date:</strong> 04 October 2014 21:56:17 +01:00 or Sat, 04 October 2014 21:56:17 +01:00</p>
<p><strong>Summary:</strong>&nbsp;The Visitor pattern can involve non-local boilerplate code. Robert Mill and Jonathan Coe present an inline Visitor in C++.</p>
<p><strong>Body:</strong>&nbsp;<p>The <span class="pattern">Visitor</span> pattern can be useful when type-specific handling is required and tight coupling of type-handling logic and handled types is either an acceptable cost or desirable in its own right. Weâ€™ve found that selective application of the classical <span class="pattern">Visitor</span> pattern adds strong compile-time safety, as the handling of new types needs explicit consideration in every context where type-specific handling occurs. The <span class="pattern">Visitor</span> pattern presents an inversion of control that can feel unnatural and often requires introduction of considerable non-local boilerplate code. Weâ€™ve found that this slows adoption of the <span class="pattern">Visitor</span> pattern especially among engineers and scientists who traditionally write their type-handling logic inline. Here we present a solution for defining <span class="pattern">Visitor</span>s inline.</p>

<h2>The problem</h2>

<p>In object-oriented programming, we may need to perform a function on an object of polymorphic type, such that the behaviour of the function is specific to the derived type. Suppose that for the abstract base class <code>Polygon</code> we derive the concrete classes <code>Triangle</code> and <code>Square</code>. The free function <code>CountSides</code>, returns the number of sides in the polygon, <code>p</code> (see Listing 1).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
struct Triangle : Polygon
{
  // members
}

struct Square : Polygon
{
  // members
}

int CountSides(Polygon&amp; p)
{
  // implementation
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 1</td>
	</tr>
</table>

<p><code>CountSides</code> will need the derived type of the polygon <code>p</code> to compute its result, which is problematic, because its argument is conveyed by a reference of the base class type, <code>Polygon</code>.</p>


<h2>Visitor pattern</h2>

<p>The <span class="pattern">Visitor</span> design pattern offers a mechanism for type-specific handling using virtual dispatch [<a href="#[Gamma95]">Gamma95</a>]. In the words of Scott Meyers: â€œ<span class="pattern">Visitor</span><em> lets you define a new operation without changing the classes of the elements on which it operates</em>â€ [<a href="#[Meyers06]">Meyers06</a>]. The pattern uses the <code>this</code> pointer inside the class to identify the derived type. Each derived object must accept a <span class="pattern">Visitor</span> interface which provides a list of <code>visit</code> members with a single argument overloaded on various derived types. To continue our illustration, the <code>PolygonVisitor</code> is able to visit <code>Triangle</code>s and <code>Square</code>s, and all these polygons must be able to accept a <code>PolygonVisitor</code>. (See Listing 2.)</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
struct Triangle; 
struct Square;

struct PolygonVisitor 
{ 
  virtual ~PolygonVisitor() {}

  virtual void visit(Triangle&amp; tr) = 0; 
  virtual void visit(Square&amp; sq) = 0;
};

struct Polygon 
{ 
  virtual void accept(PolygonVisitor&amp; v) = 0; 
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 2</td>
	</tr>
</table>

<p><code>Square</code>s and <code>Triangle</code>s accept the <span class="pattern">Visitor</span> as shown in Listing 3. Observe that the <code>this</code> pointer is used to select the appropriate overloaded function in the <span class="pattern">Visitor</span> interface.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
struct Triangle : Polygon 
{ 
  void accept(PolygonVisitor&amp; v) override 
  { 
    v.visit(*this); 
  } 
};

struct Square : Polygon 
{ 
  void accept(PolygonVisitor&amp; v) override 
  {
    v.visit(*this); 
  } 
};
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 3</td>
	</tr>
</table>

<p>A <span class="pattern">Visitor</span> object, <code>SideCounter</code>, which counts the number of sides of a polygon and stores the result, is implemented and used as in Listing 4.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
struct SideCounter : PolygonVisitor 
{ 
  void visit(Square&amp; sq) override 
  { 
    m_sides = 4; 
  }
  
  void visit(Triangle&amp; tr) override 
  { 
    m_sides = 3; 
  }
  
  int m_sides = 0; 
};

int CountSides(Polygon&amp; p) 
{ 
  SideCounter sideCounter; 
  p.accept(sideCounter);
  return sideCounter.m_sides; 
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 4</td>
	</tr>
</table>

<h2>Inline Visitor pattern</h2>

<p>One potential drawback of the <span class="pattern">Visitor</span> pattern is that it requires the creation of a new visitor object type for each algorithm that operates on the derived type. In some cases, the class created will not be reused and, much like a lambda, it would be more convenient to write the visitor clauses inline. Listing 5 shows how this can be accomplished in a form that resembles a <code>switch</code> statement.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
int CountSides(Polygon&amp; p) 
{ 
  int sides = 0;
  
  auto v = begin_visitor&lt;PolygonVisitor&gt;
    .on&lt;Triangle&gt;([&amp;sides](Triangle&amp; tr) 
    {
      sides = 3; 
    }) 
    .on&lt;Square&gt;([&amp;sides](Square&amp; sq) 
    { 
      sides = 4; 
    }) 
    .end_visitor();
  
  p.accept(v); 
  return sides; 
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 5</td>
	</tr>
</table>

<p>In Listing 6, we demonstrate generic code that permits the <code>begin_visitor</code> ... <code>end_visitor</code> construction to be used with any <code>visitor</code> base. The initial <code>begin_visitor</code> call instantiates a class which defines an inner object inheriting from the visitor interface; each subsequent call of the <code>on</code> function instantiates a class whose inner class inherits from the previous inner class implementing an additional <code>visit</code> function. Finally the <code>end_visitor</code> call returns an instance of the inner visitor class.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
template &lt;typename T,
          typename F,
          typename BaseInner,
          typename ArgsT&gt;
struct ComposeVisitor
{
  struct Inner : public BaseInner
  {
    using BaseInner::visit;
    Inner(ArgsT&amp;&amp; args) :
      BaseInner(move(args.second)),
      m_f(move(args.first))
    {
    }
    void visit(T&amp; t) final override
    {
      m_f(t);
    }
  private:
    F m_f;
  };
  ComposeVisitor(ArgsT&amp;&amp; args) :
    m_args(move(args))
  {
  }
  template &lt;typename Tadd,
            typename Fadd&gt;
  ComposeVisitor&lt;
    Tadd,
    Fadd,
    Inner,
    pair&lt;Fadd, ArgsT&gt;&gt; on(Fadd&amp;&amp; f)
  {
    return ComposeVisitor&lt;
      Tadd,
      Fadd,
      Inner,
      pair&lt;Fadd, ArgsT&gt;&gt;(
        make_pair(
          move(f),
          move(m_args)));
  }
  Inner end_visitor()
  {
    return Inner(move(m_args));
  }
  
  ArgsT m_args;
};
template &lt;typename TVisitorBase&gt;
struct EmptyVisitor
{
  struct Inner : public TVisitorBase
  {
    using TVisitorBase::visit;
    Inner(nullptr_t) {}
  };
  
  template &lt;typename Tadd, typename Fadd&gt;
  ComposeVisitor&lt;
    Tadd,
    Fadd,
    Inner,
    pair&lt;Fadd, nullptr_t&gt;&gt; on(Fadd&amp;&amp; f)
  {
    return ComposeVisitor&lt;
      Tadd,
      Fadd,
      Inner,
      pair&lt;Fadd, nullptr_t&gt;&gt;(
        make_pair(
          move(f),
          nullptr));
  }
};
template &lt;typename TVisitorBase&gt;
EmptyVisitor&lt;TVisitorBase&gt; begin_visitor()
{
  return EmptyVisitor&lt;TVisitorBase&gt;();
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 6</td>
	</tr>
</table>

<p>The consistency between the list of types used with <code>on</code> and those in the visitor base is verified at compilation time. Since the <code>override</code> qualifier is specified on the <code>visit</code> member function, it is not possible to add a superfluous <code>visit</code> which does not correspond to a type overload in the visitor base. Similarly, because the <code>final</code> qualifier is specified on the <code>visit</code> member function it is not possible to define a <code>visit</code> member function more than once. That inline visitors cannot be constructed when clauses are missing may also be considered desirable in some contexts. For instance, if a new type <code>Hexagon</code> is derived from <code>Polygon</code>, then the code base will compile only when appropriate <code>visit</code> functions been introduced to handle it. In large code bases, this may serve maintainability. If it is deemed that a visitor clause should have some default behaviour (e.g., no operation), a concrete visitor base can be passed into <code>begin_visitor</code>.</p>

<h2>Performance</h2>

<p>With optimizations turned on MSVC 2013, GCC 4.9.1 and Clang 3.4.2 compile the inline visitor without introducing any cost. GCC and Clang produce identical assembly code in the case when a <code>visitor</code> class is explicitly written out. MSVC produces different assembly code for the inline visitor and explicit visitor class; the inline visitor has been measured to run marginally faster.</p>

<h2>Other visitors</h2>

<p>Lokiâ€™s Acyclic Visitor [<a href="#[Martin]">Martin</a>] [<a href="#[Loki]">Loki</a>] removes compile-time coupling from visiting and visited classes but at the cost of introducing dynamic casts and run-time detection of unhandled types. When run-time performance and compile-time detection of unhandled types are favoured over shorter compile-times then we would recommend use of the inline visitor. The inline visitor does not have the flexibility of the Cooperative Visitor [<a href="#[Krishnamoorthi07]">Krishnamoorthi07</a>], which allows different method names and return types, but as it is intended to be lightweight this flexibility is not needed: the <code>visit</code> functions are not explicitly named and variables in local scope can be modified by lambda capture alleviating the need for a return value.</p>

<h2>Conclusion</h2>

<p>We have presented a method for defining inline visitors in standard C++. The method does not, by design, remove the tight coupling between visited and visiting class hierarchies. Performance, portability and convenience of the inline visitor mean that we would encourage its use where tight-coupling is acceptable and type-specific handling is logically localized.</p>

<h2>References</h2>

<p class="bibliomixed"><a id="[Gamma95]"></a>[Gamma95]  E. Gamma et al., <em>Design Patterns</em>, Addison-Wesley Longman, 1995.</p>

<p class="bibliomixed"><a id="[Krishnamoorthi07]"></a>[Krishnamoorthi07] A. S. Krishnamoorthi, â€˜The Cooperative Visitor: A Template Technique for Visitor Creationâ€™, 11 July 2007, <em>Artima Developer</em> <a href="http://www.artima.com/cppsource/cooperative_visitor.html">http://www.artima.com/cppsource/cooperative_visitor.html</a></p>

<p class="bibliomixed"><a id="[Loki]"></a>[Loki] Loki library <a href="http://loki-lib.sourceforge.net/">http://loki-lib.sourceforge.net/</a></p>

<p class="bibliomixed"><a id="[Martin]"></a>[Martin] R. C. Martin, â€˜Acyclic Visitorâ€™ <a href="http://www.objectmentor.com/resources/articles/acv.pdf">http://www.objectmentor.com/resources/articles/acv.pdf</a></p>

<p class="bibliomixed"><a id="[Meyers06]"></a>[Meyers06]  S. Meyers, â€˜My Most Important C++ Aha! Moments...Everâ€™, <em>Artima Developer</em> <a href="http://www.artima.com/cppsource/top_cpp_aha_moments.html">http://www.artima.com/cppsource/top_cpp_aha_moments.html</a></p>

</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
