• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2<html>
3<head>
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5<title>Tutorial</title>
6<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
7<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
8<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
9<link rel="up" href="../variant.html" title="Chapter 45. Boost.Variant">
10<link rel="prev" href="../variant.html" title="Chapter 45. Boost.Variant">
11<link rel="next" href="reference.html" title="Reference">
12</head>
13<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
14<table cellpadding="2" width="100%"><tr>
15<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
16<td align="center"><a href="../../../index.html">Home</a></td>
17<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
18<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
19<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
20<td align="center"><a href="../../../more/index.htm">More</a></td>
21</tr></table>
22<hr>
23<div class="spirit-nav">
24<a accesskey="p" href="../variant.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../variant.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="reference.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
25</div>
26<div class="section">
27<div class="titlepage"><div><div><h2 class="title" style="clear: both">
28<a name="variant.tutorial"></a>Tutorial</h2></div></div></div>
29<div class="toc"><dl class="toc">
30<dt><span class="section"><a href="tutorial.html#variant.tutorial.basic">Basic Usage</a></span></dt>
31<dt><span class="section"><a href="tutorial.html#variant.tutorial.advanced">Advanced Topics</a></span></dt>
32</dl></div>
33<div class="section">
34<div class="titlepage"><div><div><h3 class="title">
35<a name="variant.tutorial.basic"></a>Basic Usage</h3></div></div></div>
36<p>A discriminated union container on some set of types is defined by
37  instantiating the <code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code> class
38  template with the desired types. These types are called
39  <span class="bold"><strong>bounded types</strong></span> and are subject to the
40  requirements of the
41  <a class="link" href="reference.html#variant.concepts.bounded-type" title="BoundedType"><span class="emphasis"><em>BoundedType</em></span></a>
42  concept. Any number of bounded types may be specified, up to some
43  implementation-defined limit (see
44  <code class="computeroutput"><a class="link" href="../BOOST_VARIANT_LIMIT_TYPES.html" title="Macro BOOST_VARIANT_LIMIT_TYPES">BOOST_VARIANT_LIMIT_TYPES</a></code>).</p>
45<p>For example, the following declares a discriminated union container on
46  <code class="computeroutput">int</code> and <code class="computeroutput">std::string</code>:
47
48</p>
49<pre class="programlisting"><code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt; int, std::string &gt; v;</pre>
50<p>
51
52</p>
53<p>By default, a <code class="computeroutput">variant</code> default-constructs its first
54  bounded type, so <code class="computeroutput">v</code> initially contains <code class="computeroutput">int(0)</code>. If
55  this is not desired, or if the first bounded type is not
56  default-constructible, a <code class="computeroutput">variant</code> can be constructed
57  directly from any value convertible to one of its bounded types. Similarly,
58  a <code class="computeroutput">variant</code> can be assigned any value convertible to one of its
59  bounded types, as demonstrated in the following:
60
61</p>
62<pre class="programlisting">v = "hello";</pre>
63<p>
64
65</p>
66<p>Now <code class="computeroutput">v</code> contains a <code class="computeroutput">std::string</code> equal to
67  <code class="computeroutput">"hello"</code>. We can demonstrate this by
68  <span class="bold"><strong>streaming</strong></span> <code class="computeroutput">v</code> to standard
69  output:
70
71</p>
72<pre class="programlisting">std::cout &lt;&lt; v &lt;&lt; std::endl;</pre>
73<p>
74
75</p>
76<p>Usually though, we would like to do more with the content of a
77  <code class="computeroutput">variant</code> than streaming. Thus, we need some way to access the
78  contained value. There are two ways to accomplish this:
79  <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">apply_visitor</a></code>, which is safest
80  and very powerful, and
81  <code class="computeroutput"><a class="link" href="../boost/get.html" title="Function get">get</a>&lt;T&gt;</code>, which is
82  sometimes more convenient to use.</p>
83<p>For instance, suppose we wanted to concatenate to the string contained
84  in <code class="computeroutput">v</code>. With <span class="bold"><strong>value retrieval</strong></span>
85  by <code class="computeroutput"><a class="link" href="../boost/get.html" title="Function get">get</a></code>, this may be accomplished
86  quite simply, as seen in the following:
87
88</p>
89<pre class="programlisting">std::string&amp; str = <code class="computeroutput"><a class="link" href="../boost/get.html" title="Function get">boost::get</a></code>&lt;std::string&gt;(v);
90str += " world! ";</pre>
91<p>
92
93</p>
94<p>As desired, the <code class="computeroutput">std::string</code> contained by <code class="computeroutput">v</code> now
95  is equal to <code class="computeroutput">"hello world! "</code>. Again, we can demonstrate this by
96  streaming <code class="computeroutput">v</code> to standard output:
97
98</p>
99<pre class="programlisting">std::cout &lt;&lt; v &lt;&lt; std::endl;</pre>
100<p>
101
102</p>
103<p>While use of <code class="computeroutput">get</code> is perfectly acceptable in this trivial
104  example, <code class="computeroutput">get</code> generally suffers from several significant
105  shortcomings. For instance, if we were to write a function accepting a
106  <code class="computeroutput">variant&lt;int, std::string&gt;</code>, we would not know whether
107  the passed <code class="computeroutput">variant</code> contained an <code class="computeroutput">int</code> or a
108  <code class="computeroutput">std::string</code>. If we insisted upon continued use of
109  <code class="computeroutput">get</code>, we would need to query the <code class="computeroutput">variant</code> for its
110  contained type. The following function, which "doubles" the
111  content of the given <code class="computeroutput">variant</code>, demonstrates this approach:
112
113</p>
114<pre class="programlisting">void times_two( boost::variant&lt; int, std::string &gt; &amp; operand )
115{
116    if ( int* pi = <code class="computeroutput"><a class="link" href="../boost/get.html" title="Function get">boost::get</a></code>&lt;int&gt;( &amp;operand ) )
117        *pi *= 2;
118    else if ( std::string* pstr = <code class="computeroutput"><a class="link" href="../boost/get.html" title="Function get">boost::get</a></code>&lt;std::string&gt;( &amp;operand ) )
119        *pstr += *pstr;
120}</pre>
121<p>
122
123</p>
124<p>However, such code is quite brittle, and without careful attention will
125  likely lead to the introduction of subtle logical errors detectable only at
126  runtime. For instance, consider if we wished to extend
127  <code class="computeroutput">times_two</code> to operate on a <code class="computeroutput">variant</code> with additional
128  bounded types. Specifically, let's add
129  <code class="computeroutput">std::complex&lt;double&gt;</code> to the set. Clearly, we would need
130  to at least change the function declaration:
131
132</p>
133<pre class="programlisting">void times_two( boost::variant&lt; int, std::string, std::complex&lt;double&gt; &gt; &amp; operand )
134{
135    // as above...?
136}</pre>
137<p>
138
139</p>
140<p>Of course, additional changes are required, for currently if the passed
141  <code class="computeroutput">variant</code> in fact contained a <code class="computeroutput">std::complex</code> value,
142  <code class="computeroutput">times_two</code> would silently return -- without any of the desired
143  side-effects and without any error. In this case, the fix is obvious. But in
144  more complicated programs, it could take considerable time to identify and
145  locate the error in the first place.</p>
146<p>Thus, real-world use of <code class="computeroutput">variant</code> typically demands an access
147  mechanism more robust than <code class="computeroutput">get</code>. For this reason,
148  <code class="computeroutput">variant</code> supports compile-time checked
149  <span class="bold"><strong>visitation</strong></span> via
150  <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">apply_visitor</a></code>. Visitation requires
151  that the programmer explicitly handle (or ignore) each bounded type. Failure
152  to do so results in a compile-time error.</p>
153<p>Visitation of a <code class="computeroutput">variant</code> requires a visitor object. The
154  following demonstrates one such implementation of a visitor implementating
155  behavior identical to <code class="computeroutput">times_two</code>:
156
157</p>
158<pre class="programlisting">class times_two_visitor
159    : public <code class="computeroutput"><a class="link" href="../boost/static_visitor.html" title="Class template static_visitor">boost::static_visitor</a></code>&lt;&gt;
160{
161public:
162
163    void operator()(int &amp; i) const
164    {
165        i *= 2;
166    }
167
168    void operator()(std::string &amp; str) const
169    {
170        str += str;
171    }
172
173};</pre>
174<p>
175
176</p>
177<p>With the implementation of the above visitor, we can then apply it to
178  <code class="computeroutput">v</code>, as seen in the following:
179
180</p>
181<pre class="programlisting"><code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>( times_two_visitor(), v );</pre>
182<p>
183
184</p>
185<p>As expected, the content of <code class="computeroutput">v</code> is now a
186  <code class="computeroutput">std::string</code> equal to <code class="computeroutput">"hello world! hello world! "</code>.
187  (We'll skip the verification this time.)</p>
188<p>In addition to enhanced robustness, visitation provides another
189  important advantage over <code class="computeroutput">get</code>: the ability to write generic
190  visitors. For instance, the following visitor will "double" the
191  content of <span class="emphasis"><em>any</em></span> <code class="computeroutput">variant</code> (provided its
192  bounded types each support operator+=):
193
194</p>
195<pre class="programlisting">class times_two_generic
196    : public <code class="computeroutput"><a class="link" href="../boost/static_visitor.html" title="Class template static_visitor">boost::static_visitor</a></code>&lt;&gt;
197{
198public:
199
200    template &lt;typename T&gt;
201    void operator()( T &amp; operand ) const
202    {
203        operand += operand;
204    }
205
206};</pre>
207<p>
208
209</p>
210<p>Again, <code class="computeroutput">apply_visitor</code> sets the wheels in motion:
211
212</p>
213<pre class="programlisting"><code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>( times_two_generic(), v );</pre>
214<p>
215
216</p>
217<p>While the initial setup costs of visitation may exceed that required for
218  <code class="computeroutput">get</code>, the benefits quickly become significant. Before concluding
219  this section, we should explore one last benefit of visitation with
220  <code class="computeroutput">apply_visitor</code>:
221  <span class="bold"><strong>delayed visitation</strong></span>. Namely, a special form
222  of <code class="computeroutput">apply_visitor</code> is available that does not immediately apply
223  the given visitor to any <code class="computeroutput">variant</code> but rather returns a function
224  object that operates on any <code class="computeroutput">variant</code> given to it. This behavior
225  is particularly useful when operating on sequences of <code class="computeroutput">variant</code>
226  type, as the following demonstrates:
227
228</p>
229<pre class="programlisting">std::vector&lt; <code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt;int, std::string&gt; &gt; vec;
230vec.push_back( 21 );
231vec.push_back( "hello " );
232
233times_two_generic visitor;
234std::for_each(
235      vec.begin(), vec.end()
236   , <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>(visitor)
237   );</pre>
238<p>
239
240</p>
241</div>
242<div class="section">
243<div class="titlepage"><div><div><h3 class="title">
244<a name="variant.tutorial.advanced"></a>Advanced Topics</h3></div></div></div>
245<div class="toc"><dl class="toc">
246<dt><span class="section"><a href="tutorial.html#variant.tutorial.preprocessor">Preprocessor macros</a></span></dt>
247<dt><span class="section"><a href="tutorial.html#variant.tutorial.over-sequence">Using a type sequence to specify bounded types</a></span></dt>
248<dt><span class="section"><a href="tutorial.html#variant.tutorial.recursive">Recursive <code class="computeroutput">variant</code> types</a></span></dt>
249<dt><span class="section"><a href="tutorial.html#variant.tutorial.binary-visitation">Binary visitation</a></span></dt>
250<dt><span class="section"><a href="tutorial.html#variant.tutorial.multi-visitation">Multi visitation</a></span></dt>
251</dl></div>
252<p>This section discusses several features of the library often required
253  for advanced uses of <code class="computeroutput">variant</code>. Unlike in the above section, each
254  feature presented below is largely independent of the others. Accordingly,
255  this section is not necessarily intended to be read linearly or in its
256  entirety.</p>
257<div class="section">
258<div class="titlepage"><div><div><h4 class="title">
259<a name="variant.tutorial.preprocessor"></a>Preprocessor macros</h4></div></div></div>
260<p>While the <code class="computeroutput">variant</code> class template's variadic parameter
261    list greatly simplifies use for specific instantiations of the template,
262    it significantly complicates use for generic instantiations. For instance,
263    while it is immediately clear how one might write a function accepting a
264    specific <code class="computeroutput">variant</code> instantiation, say
265    <code class="computeroutput">variant&lt;int, std::string&gt;</code>, it is less clear how one
266    might write a function accepting any given <code class="computeroutput">variant</code>.</p>
267<p>Due to the lack of support for true variadic template parameter lists
268    in the C++98 standard, the preprocessor is needed. While the
269    Preprocessor library provides a general and
270    powerful solution, the need to repeat
271    <code class="computeroutput"><a class="link" href="../BOOST_VARIANT_LIMIT_TYPES.html" title="Macro BOOST_VARIANT_LIMIT_TYPES">BOOST_VARIANT_LIMIT_TYPES</a></code>
272    unnecessarily clutters otherwise simple code. Therefore, for common
273    use-cases, this library provides its own macro
274    <code class="computeroutput"><span class="bold"><strong><a class="link" href="../BOOST_VARIANT_ENUM_PARAMS.html" title="Macro BOOST_VARIANT_ENUM_PARAMS">BOOST_VARIANT_ENUM_PARAMS</a></strong></span></code>.</p>
275<p>This macro simplifies for the user the process of declaring
276    <code class="computeroutput">variant</code> types in function templates or explicit partial
277    specializations of class templates, as shown in the following:
278
279</p>
280<pre class="programlisting">// general cases
281template &lt;typename T&gt; void some_func(const T &amp;);
282template &lt;typename T&gt; class some_class;
283
284// function template overload
285template &lt;<code class="computeroutput"><a class="link" href="../BOOST_VARIANT_ENUM_PARAMS.html" title="Macro BOOST_VARIANT_ENUM_PARAMS">BOOST_VARIANT_ENUM_PARAMS</a></code>(typename T)&gt;
286void some_func(const <code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt;<code class="computeroutput"><a class="link" href="../BOOST_VARIANT_ENUM_PARAMS.html" title="Macro BOOST_VARIANT_ENUM_PARAMS">BOOST_VARIANT_ENUM_PARAMS</a></code>(T)&gt; &amp;);
287
288// explicit partial specialization
289template &lt;<code class="computeroutput"><a class="link" href="../BOOST_VARIANT_ENUM_PARAMS.html" title="Macro BOOST_VARIANT_ENUM_PARAMS">BOOST_VARIANT_ENUM_PARAMS</a></code>(typename T)&gt;
290class some_class&lt; <code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt;<code class="computeroutput"><a class="link" href="../BOOST_VARIANT_ENUM_PARAMS.html" title="Macro BOOST_VARIANT_ENUM_PARAMS">BOOST_VARIANT_ENUM_PARAMS</a></code>(T)&gt; &gt;;</pre>
291<p>
292
293  </p>
294</div>
295<div class="section">
296<div class="titlepage"><div><div><h4 class="title">
297<a name="variant.tutorial.over-sequence"></a>Using a type sequence to specify bounded types</h4></div></div></div>
298<p>While convenient for typical uses, the <code class="computeroutput">variant</code> class
299    template's variadic template parameter list is limiting in two significant
300    dimensions. First, due to the lack of support for true variadic template
301    parameter lists in C++, the number of parameters must be limited to some
302    implementation-defined maximum (namely,
303    <code class="computeroutput"><a class="link" href="../BOOST_VARIANT_LIMIT_TYPES.html" title="Macro BOOST_VARIANT_LIMIT_TYPES">BOOST_VARIANT_LIMIT_TYPES</a></code>).
304    Second, the nature of parameter lists in general makes compile-time
305    manipulation of the lists excessively difficult.</p>
306<p>To solve these problems,
307    <code class="computeroutput">make_variant_over&lt; <span class="emphasis"><em>Sequence</em></span> &gt;</code>
308    exposes a <code class="computeroutput">variant</code> whose bounded types are the elements of
309    <code class="computeroutput">Sequence</code> (where <code class="computeroutput">Sequence</code> is any type fulfilling
310    the requirements of MPL's
311    <span class="emphasis"><em>Sequence</em></span> concept). For instance,
312
313</p>
314<pre class="programlisting">typedef <code class="computeroutput">mpl::vector</code>&lt; std::string &gt; types_initial;
315typedef <code class="computeroutput">mpl::push_front</code>&lt; types_initial, int &gt;::type types;
316
317<code class="computeroutput"><a class="link" href="../boost/make_variant_over.html" title="Class template make_variant_over">boost::make_variant_over</a></code>&lt; types &gt;::type v1;</pre>
318<p>
319
320    behaves equivalently to
321
322</p>
323<pre class="programlisting"><code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt; int, std::string &gt; v2;</pre>
324<p>
325
326  </p>
327<p><span class="bold"><strong>Portability</strong></span>: Unfortunately, due to
328    standard conformance issues in several compilers,
329    <code class="computeroutput">make_variant_over</code> is not universally available. On these
330    compilers the library indicates its lack of support for the syntax via the
331    definition of the preprocessor symbol
332    <code class="computeroutput"><a class="link" href="../BOOST_VARIANT_1_3_46_5_3_7.html" title="Macro BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT">BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT</a></code>.</p>
333</div>
334<div class="section">
335<div class="titlepage"><div><div><h4 class="title">
336<a name="variant.tutorial.recursive"></a>Recursive <code class="computeroutput">variant</code> types</h4></div></div></div>
337<div class="toc"><dl class="toc">
338<dt><span class="section"><a href="tutorial.html#variant.tutorial.recursive.recursive-wrapper">Recursive types with <code class="computeroutput">recursive_wrapper</code></a></span></dt>
339<dt><span class="section"><a href="tutorial.html#variant.tutorial.recursive.recursive-variant">Recursive types with <code class="computeroutput">make_recursive_variant</code></a></span></dt>
340</dl></div>
341<p>Recursive types facilitate the construction of complex semantics from
342    simple syntax. For instance, nearly every programmer is familiar with the
343    canonical definition of a linked list implementation, whose simple
344    definition allows sequences of unlimited length:
345
346</p>
347<pre class="programlisting">template &lt;typename T&gt;
348struct list_node
349{
350    T data;
351    list_node * next;
352};</pre>
353<p>
354
355  </p>
356<p>The nature of <code class="computeroutput">variant</code> as a generic class template
357    unfortunately precludes the straightforward construction of recursive
358    <code class="computeroutput">variant</code> types. Consider the following attempt to construct
359    a structure for simple mathematical expressions:
360
361    </p>
362<pre class="programlisting">struct add;
363struct sub;
364template &lt;typename OpTag&gt; struct binary_op;
365
366typedef <code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt;
367      int
368    , binary_op&lt;add&gt;
369    , binary_op&lt;sub&gt;
370    &gt; expression;
371
372template &lt;typename OpTag&gt;
373struct binary_op
374{
375    expression left;  // <span class="emphasis"><em>variant instantiated here...</em></span>
376    expression right;
377
378    binary_op( const expression &amp; lhs, const expression &amp; rhs )
379        : left(lhs), right(rhs)
380    {
381    }
382
383}; // <span class="emphasis"><em>...but binary_op not complete until here!</em></span></pre>
384<p>
385
386  </p>
387<p>While well-intentioned, the above approach will not compile because
388    <code class="computeroutput">binary_op</code> is still incomplete when the <code class="computeroutput">variant</code>
389    type <code class="computeroutput">expression</code> is instantiated. Further, the approach suffers
390    from a more significant logical flaw: even if C++ syntax were different
391    such that the above example could be made to "work,"
392    <code class="computeroutput">expression</code> would need to be of infinite size, which is
393    clearly impossible.</p>
394<p>To overcome these difficulties, <code class="computeroutput">variant</code> includes special
395    support for the
396    <code class="computeroutput"><a class="link" href="../boost/recursive_wrapper.html" title="Class template recursive_wrapper">boost::recursive_wrapper</a></code> class
397    template, which breaks the circular dependency at the heart of these
398    problems. Further,
399    <code class="computeroutput"><a class="link" href="../boost/make_recursive_variant.html" title="Class template make_recursive_variant">boost::make_recursive_variant</a></code> provides
400    a more convenient syntax for declaring recursive <code class="computeroutput">variant</code>
401    types. Tutorials for use of these facilities is described in
402    <a class="xref" href="tutorial.html#variant.tutorial.recursive.recursive-wrapper" title="Recursive types with recursive_wrapper">the section called “Recursive types with <code class="computeroutput">recursive_wrapper</code>”</a> and
403    <a class="xref" href="tutorial.html#variant.tutorial.recursive.recursive-variant" title="Recursive types with make_recursive_variant">the section called “Recursive types with <code class="computeroutput">make_recursive_variant</code>”</a>.</p>
404<div class="section">
405<div class="titlepage"><div><div><h5 class="title">
406<a name="variant.tutorial.recursive.recursive-wrapper"></a>Recursive types with <code class="computeroutput">recursive_wrapper</code>
407</h5></div></div></div>
408<p>The following example demonstrates how <code class="computeroutput">recursive_wrapper</code>
409    could be used to solve the problem presented in
410    <a class="xref" href="tutorial.html#variant.tutorial.recursive" title="Recursive variant types">the section called “Recursive <code class="computeroutput">variant</code> types”</a>:
411
412    </p>
413<pre class="programlisting">typedef <code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt;
414      int
415    , <code class="computeroutput"><a class="link" href="../boost/recursive_wrapper.html" title="Class template recursive_wrapper">boost::recursive_wrapper</a></code>&lt; binary_op&lt;add&gt; &gt;
416    , <code class="computeroutput"><a class="link" href="../boost/recursive_wrapper.html" title="Class template recursive_wrapper">boost::recursive_wrapper</a></code>&lt; binary_op&lt;sub&gt; &gt;
417    &gt; expression;</pre>
418<p>
419
420  </p>
421<p>Because <code class="computeroutput">variant</code> provides special support for
422    <code class="computeroutput">recursive_wrapper</code>, clients may treat the resultant
423    <code class="computeroutput">variant</code> as though the wrapper were not present. This is seen
424    in the implementation of the following visitor, which calculates the value
425    of an <code class="computeroutput">expression</code> without any reference to
426    <code class="computeroutput">recursive_wrapper</code>:
427
428    </p>
429<pre class="programlisting">class calculator : public <code class="computeroutput"><a class="link" href="../boost/static_visitor.html" title="Class template static_visitor">boost::static_visitor&lt;int&gt;</a></code>
430{
431public:
432
433    int operator()(int value) const
434    {
435        return value;
436    }
437
438    int operator()(const binary_op&lt;add&gt; &amp; binary) const
439    {
440        return <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>( calculator(), binary.left )
441             + <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>( calculator(), binary.right );
442    }
443
444    int operator()(const binary_op&lt;sub&gt; &amp; binary) const
445    {
446        return <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>( calculator(), binary.left )
447             - <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>( calculator(), binary.right );
448    }
449
450};</pre>
451<p>
452
453  </p>
454<p>Finally, we can demonstrate <code class="computeroutput">expression</code> in action:
455
456    </p>
457<pre class="programlisting">void f()
458{
459    // result = ((7-3)+8) = 12
460    expression result(
461        binary_op&lt;add&gt;(
462            binary_op&lt;sub&gt;(7,3)
463          , 8
464          )
465      );
466
467    assert( <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>(calculator(),result) == 12 );
468}</pre>
469<p>
470
471  </p>
472<p><span class="bold"><strong>Performance</strong></span>: <code class="computeroutput"><a class="link" href="../boost/recursive_wrapper.html" title="Class template recursive_wrapper">boost::recursive_wrapper</a></code>
473    has no empty state, which makes its move constructor not very optimal. Consider using <code class="computeroutput">std::unique_ptr</code>
474    or some other safe pointer for better performance on C++11 compatible compilers.</p>
475</div>
476<div class="section">
477<div class="titlepage"><div><div><h5 class="title">
478<a name="variant.tutorial.recursive.recursive-variant"></a>Recursive types with <code class="computeroutput">make_recursive_variant</code>
479</h5></div></div></div>
480<p>For some applications of recursive <code class="computeroutput">variant</code> types, a user
481    may be able to sacrifice the full flexibility of using
482    <code class="computeroutput">recursive_wrapper</code> with <code class="computeroutput">variant</code> for the following
483    convenient syntax:
484
485</p>
486<pre class="programlisting">typedef <code class="computeroutput"><a class="link" href="../boost/make_recursive_variant.html" title="Class template make_recursive_variant">boost::make_recursive_variant</a></code>&lt;
487      int
488    , std::vector&lt; boost::recursive_variant_ &gt;
489    &gt;::type int_tree_t;</pre>
490<p>
491
492  </p>
493<p>Use of the resultant <code class="computeroutput">variant</code> type is as expected:
494
495</p>
496<pre class="programlisting">std::vector&lt; int_tree_t &gt; subresult;
497subresult.push_back(3);
498subresult.push_back(5);
499
500std::vector&lt; int_tree_t &gt; result;
501result.push_back(1);
502result.push_back(subresult);
503result.push_back(7);
504
505int_tree_t var(result);</pre>
506<p>
507
508  </p>
509<p>To be clear, one might represent the resultant content of
510    <code class="computeroutput">var</code> as <code class="computeroutput">( 1 ( 3 5 ) 7 )</code>.</p>
511<p>Finally, note that a type sequence can be used to specify the bounded
512    types of a recursive <code class="computeroutput">variant</code> via the use of
513    <code class="computeroutput"><a class="link" href="../boost/make_recurs_1_3_46_5_5_1_3.html" title="Class template make_recursive_variant_over">boost::make_recursive_variant_over</a></code>,
514    whose semantics are the same as <code class="computeroutput">make_variant_over</code> (which is
515    described in <a class="xref" href="tutorial.html#variant.tutorial.over-sequence" title="Using a type sequence to specify bounded types">the section called “Using a type sequence to specify bounded types”</a>).</p>
516<p><span class="bold"><strong>Portability</strong></span>: Unfortunately, due to
517    standard conformance issues in several compilers,
518    <code class="computeroutput">make_recursive_variant</code> is not universally supported. On these
519    compilers the library indicates its lack of support via the definition
520    of the preprocessor symbol
521    <code class="computeroutput"><a class="link" href="../BOOST_VARIANT_1_3_46_5_3_9.html" title="Macro BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT">BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT</a></code>.
522    Thus, unless working with highly-conformant compilers, maximum portability
523    will be achieved by instead using <code class="computeroutput">recursive_wrapper</code>, as
524    described in
525    <a class="xref" href="tutorial.html#variant.tutorial.recursive.recursive-wrapper" title="Recursive types with recursive_wrapper">the section called “Recursive types with <code class="computeroutput">recursive_wrapper</code>”</a>.</p>
526</div>
527</div>
528<div class="section">
529<div class="titlepage"><div><div><h4 class="title">
530<a name="variant.tutorial.binary-visitation"></a>Binary visitation</h4></div></div></div>
531<p>As the tutorial above demonstrates, visitation is a powerful mechanism
532    for manipulating <code class="computeroutput">variant</code> content. Binary visitation further
533    extends the power and flexibility of visitation by allowing simultaneous
534    visitation of the content of two different <code class="computeroutput">variant</code>
535    objects.</p>
536<p>Notably this feature requires that binary visitors are incompatible
537    with the visitor objects discussed in the tutorial above, as they must
538    operate on two arguments. The following demonstrates the implementation of
539    a binary visitor:
540
541</p>
542<pre class="programlisting">class are_strict_equals
543    : public <code class="computeroutput"><a class="link" href="../boost/static_visitor.html" title="Class template static_visitor">boost::static_visitor</a></code>&lt;bool&gt;
544{
545public:
546
547    template &lt;typename T, typename U&gt;
548    bool operator()( const T &amp;, const U &amp; ) const
549    {
550        return false; // cannot compare different types
551    }
552
553    template &lt;typename T&gt;
554    bool operator()( const T &amp; lhs, const T &amp; rhs ) const
555    {
556        return lhs == rhs;
557    }
558
559};</pre>
560<p>
561
562  </p>
563<p>As expected, the visitor is applied to two <code class="computeroutput">variant</code>
564    arguments by means of <code class="computeroutput">apply_visitor</code>:
565
566</p>
567<pre class="programlisting"><code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt; int, std::string &gt; v1( "hello" );
568
569<code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt; double, std::string &gt; v2( "hello" );
570assert( <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>(are_strict_equals(), v1, v2) );
571
572<code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt; int, const char * &gt; v3( "hello" );
573assert( !<code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>(are_strict_equals(), v1, v3) );</pre>
574<p>
575
576  </p>
577<p>Finally, we must note that the function object returned from the
578    "delayed" form of
579    <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">apply_visitor</a></code> also supports
580    binary visitation, as the following demonstrates:
581
582</p>
583<pre class="programlisting">typedef <code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt;double, std::string&gt; my_variant;
584
585std::vector&lt; my_variant &gt; seq1;
586seq1.push_back("pi is close to ");
587seq1.push_back(3.14);
588
589std::list&lt; my_variant &gt; seq2;
590seq2.push_back("pi is close to ");
591seq2.push_back(3.14);
592
593are_strict_equals visitor;
594assert( std::equal(
595      seq1.begin(), seq1.end(), seq2.begin()
596    , <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>( visitor )
597    ) );</pre>
598<p>
599
600  </p>
601</div>
602<div class="section">
603<div class="titlepage"><div><div><h4 class="title">
604<a name="variant.tutorial.multi-visitation"></a>Multi visitation</h4></div></div></div>
605<p>Multi visitation extends the power and flexibility of visitation by allowing simultaneous
606    visitation of the content of three and more different <code class="computeroutput">variant</code>
607    objects. Note that header for multi visitors shall be included separately.</p>
608<p>Notably this feature requires that multi visitors are incompatible
609    with the visitor objects discussed in the tutorial above, as they must
610    operate on same amout of arguments that was passed to <code class="computeroutput">apply_visitor</code>.
611    The following demonstrates the implementation of a multi visitor for three parameters:
612
613</p>
614<pre class="programlisting">
615#include &lt;boost/variant/multivisitors.hpp&gt;
616
617typedef <code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt;int, double, bool&gt; bool_like_t;
618typedef <code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt;int, double&gt; arithmetics_t;
619
620struct if_visitor: public <code class="computeroutput"><a class="link" href="../boost/static_visitor.html" title="Class template static_visitor">boost::static_visitor</a></code>&lt;arithmetics_t&gt; {
621    template &lt;class T1, class T2&gt;
622    arithmetics_t operator()(bool b, T1 v1, T2 v2) const {
623        if (b) {
624            return v1;
625        } else {
626            return v2;
627        }
628    }
629};
630</pre>
631<p>
632  </p>
633<p>As expected, the visitor is applied to three <code class="computeroutput">variant</code>
634    arguments by means of <code class="computeroutput">apply_visitor</code>:
635
636</p>
637<pre class="programlisting">
638bool_like_t v0(true), v1(1), v2(2.0);
639
640assert(
641    <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>(if_visitor(), v0, v1, v2)
642    ==
643    arithmetics_t(1)
644);
645</pre>
646<p>
647  </p>
648<p>Finally, we must note that multi visitation does not support
649    "delayed" form of
650    <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">apply_visitor</a> if
651    <a class="link" href="../BOOST_VARIANT_1_3_46_5_3_4.html" title="Macro BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES">BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES</a> is defined</code>.
652  </p>
653</div>
654</div>
655</div>
656<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
657<td align="left"></td>
658<td align="right"><div class="copyright-footer">Copyright © 2002, 2003 Eric Friedman, Itay Maman<br>Copyright © 2014-2020 Antony Polukhin<p>Distributed under the Boost Software License, Version 1.0.
659    (See accompanying file <code class="filename">LICENSE_1_0.txt</code> or copy at
660    <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
661    </p>
662</div></td>
663</tr></table>
664<hr>
665<div class="spirit-nav">
666<a accesskey="p" href="../variant.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../variant.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="reference.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
667</div>
668</body>
669</html>
670