[DEV] add v1.76.0

This commit is contained in:
2021-10-05 21:37:46 +02:00
parent a97e9ae7d4
commit d0115b733d
45133 changed files with 4744437 additions and 1026325 deletions

View File

@@ -0,0 +1,326 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Design Overview</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../variant.html" title="Chapter 46. Boost.Variant">
<link rel="prev" href="../boost/visitor_ptr.html" title="Function template visitor_ptr">
<link rel="next" href="misc.html" title="Miscellaneous Notes">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../boost/visitor_ptr.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="misc.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="variant.design"></a>Design Overview</h2></div></div></div>
<div class="toc"><dl class="toc"><dt><span class="section"><a href="design.html#variant.design.never-empty">"Never-Empty" Guarantee</a></span></dt></dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="variant.design.never-empty"></a>"Never-Empty" Guarantee</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="design.html#variant.design.never-empty.guarantee">The Guarantee</a></span></dt>
<dt><span class="section"><a href="design.html#variant.design.never-empty.problem">The Implementation Problem</a></span></dt>
<dt><span class="section"><a href="design.html#variant.design.never-empty.memcpy-solution">The "Ideal" Solution: False Hopes</a></span></dt>
<dt><span class="section"><a href="design.html#variant.design.never-empty.double-storage-solution">An Initial Solution: Double Storage</a></span></dt>
<dt><span class="section"><a href="design.html#variant.design.never-empty.heap-backup-solution">Current Approach: Temporary Heap Backup</a></span></dt>
<dt><span class="section"><a href="design.html#variant.design.never-empty.optimizations">Enabling Optimizations</a></span></dt>
<dt><span class="section"><a href="design.html#variant.design.never-empty.roadmap">Future Direction: Policy-based Implementation</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.design.never-empty.guarantee"></a>The Guarantee</h4></div></div></div>
<p>All instances <code class="computeroutput">v</code> of type
<code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">variant</a>&lt;T1,T2,...,TN&gt;</code>
guarantee that <code class="computeroutput">v</code> has constructed content of one of the
types <code class="computeroutput">T<span class="emphasis"><em>i</em></span></code>, even if an operation on
<code class="computeroutput">v</code> has previously failed.</p>
<p>This implies that <code class="computeroutput">variant</code> may be viewed precisely as
a union of <span class="emphasis"><em>exactly</em></span> its bounded types. This
"never-empty" property insulates the user from the
possibility of undefined <code class="computeroutput">variant</code> content and the
significant additional complexity-of-use attendant with such a
possibility.</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.design.never-empty.problem"></a>The Implementation Problem</h4></div></div></div>
<p>While the
<a class="link" href="design.html#variant.design.never-empty.guarantee" title="The Guarantee">never-empty guarantee</a>
might at first seem "obvious," it is in fact not even
straightforward how to implement it in general (i.e., without
unreasonably restrictive additional requirements on
<a class="link" href="reference.html#variant.concepts.bounded-type" title="BoundedType">bounded types</a>).</p>
<p>The central difficulty emerges in the details of
<code class="computeroutput">variant</code> assignment. Given two instances <code class="computeroutput">v1</code>
and <code class="computeroutput">v2</code> of some concrete <code class="computeroutput">variant</code> type, there
are two distinct, fundamental cases we must consider for the assignment
<code class="computeroutput">v1 = v2</code>.</p>
<p>First consider the case that <code class="computeroutput">v1</code> and <code class="computeroutput">v2</code>
each contains a value of the same type. Call this type <code class="computeroutput">T</code>.
In this situation, assignment is perfectly straightforward: use
<code class="computeroutput">T::operator=</code>.</p>
<p>However, we must also consider the case that <code class="computeroutput">v1</code> and
<code class="computeroutput">v2</code> contain values <span class="emphasis"><em>of distinct types</em></span>.
Call these types <code class="computeroutput">T</code> and <code class="computeroutput">U</code>. At this point,
since <code class="computeroutput">variant</code> manages its content on the stack, the
left-hand side of the assignment (i.e., <code class="computeroutput">v1</code>) must destroy
its content so as to permit in-place copy-construction of the content
of the right-hand side (i.e., <code class="computeroutput">v2</code>). In the end, whereas
<code class="computeroutput">v1</code> began with content of type <code class="computeroutput">T</code>, it ends
with content of type <code class="computeroutput">U</code>, namely a copy of the content of
<code class="computeroutput">v2</code>.</p>
<p>The crux of the problem, then, is this: in the event that
copy-construction of the content of <code class="computeroutput">v2</code> fails, how can
<code class="computeroutput">v1</code> maintain its "never-empty" guarantee?
By the time copy-construction from <code class="computeroutput">v2</code> is attempted,
<code class="computeroutput">v1</code> has already destroyed its content!</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.design.never-empty.memcpy-solution"></a>The "Ideal" Solution: False Hopes</h4></div></div></div>
<p>Upon learning of this dilemma, clever individuals may propose the
following scheme hoping to solve the problem:
</p>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">Provide some "backup" storage, appropriately
aligned, capable of holding values of the contained type of the
left-hand side.</li>
<li class="listitem">Copy the memory (e.g., using <code class="computeroutput">memcpy</code>) of the
storage of the left-hand side to the backup storage.</li>
<li class="listitem">Attempt a copy of the right-hand side content to the
(now-replicated) left-hand side storage.</li>
<li class="listitem">In the event of an exception from the copy, restore the
backup (i.e., copy the memory from the backup storage back into
the left-hand side storage).</li>
<li class="listitem">Otherwise, in the event of success, now copy the memory
of the left-hand side storage to another "temporary"
aligned storage.</li>
<li class="listitem">Now restore the backup (i.e., again copying the memory)
to the left-hand side storage; with the "old" content
now restored, invoke the destructor of the contained type on the
storage of the left-hand side.</li>
<li class="listitem">Finally, copy the memory of the temporary storage to the
(now-empty) storage of the left-hand side.</li>
</ol></div>
<p>
</p>
<p>While complicated, it appears such a scheme could provide the
desired safety in a relatively efficient manner. In fact, several
early iterations of the library implemented this very approach.</p>
<p>Unfortunately, as Dave Abraham's first noted, the scheme results
in undefined behavior:
</p>
<div class="blockquote"><blockquote class="blockquote">
<p>"That's a lot of code to read through, but if it's
doing what I think it's doing, it's undefined behavior.</p>
<p>"Is the trick to move the bits for an existing object
into a buffer so we can tentatively construct a new object in
that memory, and later move the old bits back temporarily to
destroy the old object?</p>
<p>"The standard does not give license to do that: only one
object may have a given address at a time. See 3.8, and
particularly paragraph 4."</p>
</blockquote></div>
<p>
</p>
<p>Additionally, as close examination quickly reveals, the scheme has
the potential to create irreconcilable race-conditions in concurrent
environments.</p>
<p>Ultimately, even if the above scheme could be made to work on
certain platforms with particular compilers, it is still necessary to
find a portable solution.</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.design.never-empty.double-storage-solution"></a>An Initial Solution: Double Storage</h4></div></div></div>
<p>Upon learning of the infeasibility of the above scheme, Anthony
Williams proposed in
<a class="link" href="refs.html#variant.refs.wil02">[Wil02]</a> a scheme that served
as the basis for a portable solution in some pre-release
implementations of <code class="computeroutput">variant</code>.</p>
<p>The essential idea to this scheme, which shall be referred to as
the "double storage" scheme, is to provide enough space
within a <code class="computeroutput">variant</code> to hold two separate values of any of
the bounded types.</p>
<p>With the secondary storage, a copy the right-hand side can be
attempted without first destroying the content of the left-hand side;
accordingly, the content of the left-hand side remains available in
the event of an exception.</p>
<p>Thus, with this scheme, the <code class="computeroutput">variant</code> implementation
needs only to keep track of which storage contains the content -- and
dispatch any visitation requests, queries, etc. accordingly.</p>
<p>The most obvious flaw to this approach is the space overhead
incurred. Though some optimizations could be applied in special cases
to eliminate the need for double storage -- for certain bounded types
or in some cases entirely (see
<a class="xref" href="design.html#variant.design.never-empty.optimizations" title="Enabling Optimizations">the section called “Enabling Optimizations”</a> for more
details) -- many users on the Boost mailing list strongly objected to
the use of double storage. In particular, it was noted that the
overhead of double storage would be at play at all times -- even if
assignment to <code class="computeroutput">variant</code> never occurred. For this reason
and others, a new approach was developed.</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.design.never-empty.heap-backup-solution"></a>Current Approach: Temporary Heap Backup</h4></div></div></div>
<p>Despite the many objections to the double storage solution, it was
realized that no replacement would be without drawbacks. Thus, a
compromise was desired.</p>
<p>To this end, Dave Abrahams suggested to include the following in
the behavior specification for <code class="computeroutput">variant</code> assignment:
"<code class="computeroutput">variant</code> assignment from one type to another may
incur dynamic allocation." That is, while <code class="computeroutput">variant</code> would
continue to store its content <span class="emphasis"><em>in situ</em></span> after
construction and after assignment involving identical contained types,
<code class="computeroutput">variant</code> would store its content on the heap after
assignment involving distinct contained types.</p>
<p>The algorithm for assignment would proceed as follows:
</p>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">Copy-construct the content of the right-hand side to the
heap; call the pointer to this data <code class="computeroutput">p</code>.</li>
<li class="listitem">Destroy the content of the left-hand side.</li>
<li class="listitem">Copy <code class="computeroutput">p</code> to the left-hand side
storage.</li>
</ol></div>
<p>
Since all operations on pointers are nothrow, this scheme would allow
<code class="computeroutput">variant</code> to meet its never-empty guarantee.
</p>
<p>The most obvious concern with this approach is that while it
certainly eliminates the space overhead of double storage, it
introduces the overhead of dynamic-allocation to <code class="computeroutput">variant</code>
assignment -- not just in terms of the initial allocation but also
as a result of the continued storage of the content on the heap. While
the former problem is unavoidable, the latter problem may be avoided
with the following "temporary heap backup" technique:
</p>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">Copy-construct the content of the
<span class="emphasis"><em>left</em></span>-hand side to the heap; call the pointer to
this data <code class="computeroutput">backup</code>.</li>
<li class="listitem">Destroy the content of the left-hand side.</li>
<li class="listitem">Copy-construct the content of the right-hand side in the
(now-empty) storage of the left-hand side.</li>
<li class="listitem">In the event of failure, copy <code class="computeroutput">backup</code> to the
left-hand side storage.</li>
<li class="listitem">In the event of success, deallocate the data pointed to
by <code class="computeroutput">backup</code>.</li>
</ol></div>
<p>
</p>
<p>With this technique: 1) only a single storage is used;
2) allocation is on the heap in the long-term only if the assignment
fails; and 3) after any <span class="emphasis"><em>successful</em></span> assignment,
storage within the <code class="computeroutput">variant</code> is guaranteed. For the
purposes of the initial release of the library, these characteristics
were deemed a satisfactory compromise solution.</p>
<p>There remain notable shortcomings, however. In particular, there
may be some users for which heap allocation must be avoided at all
costs; for other users, any allocation may need to occur via a
user-supplied allocator. These issues will be addressed in the future
(see <a class="xref" href="design.html#variant.design.never-empty.roadmap" title="Future Direction: Policy-based Implementation">the section called “Future Direction: Policy-based Implementation”</a>). For now,
though, the library treats storage of its content as an implementation
detail. Nonetheless, as described in the next section, there
<span class="emphasis"><em>are</em></span> certain things the user can do to ensure the
greatest efficiency for <code class="computeroutput">variant</code> instances (see
<a class="xref" href="design.html#variant.design.never-empty.optimizations" title="Enabling Optimizations">the section called “Enabling Optimizations”</a> for
details).</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.design.never-empty.optimizations"></a>Enabling Optimizations</h4></div></div></div>
<p>As described in
<a class="xref" href="design.html#variant.design.never-empty.problem" title="The Implementation Problem">the section called “The Implementation Problem”</a>, the central
difficulty in implementing the never-empty guarantee is the
possibility of failed copy-construction during <code class="computeroutput">variant</code>
assignment. Yet types with nothrow copy constructors clearly never
face this possibility. Similarly, if one of the bounded types of the
<code class="computeroutput">variant</code> is nothrow default-constructible, then such a
type could be used as a safe "fallback" type in the event of
failed copy construction.</p>
<p>Accordingly, <code class="computeroutput">variant</code> is designed to enable the
following optimizations once the following criteria on its bounded
types are met:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">For each bounded type <code class="computeroutput">T</code> that is nothrow
copy-constructible (as indicated by
<code class="computeroutput">boost::has_nothrow_copy</code>), the
library guarantees <code class="computeroutput">variant</code> will use only single
storage and in-place construction for <code class="computeroutput">T</code>.</li>
<li class="listitem">If <span class="emphasis"><em>any</em></span> bounded type is nothrow
default-constructible (as indicated by
<code class="computeroutput">boost::has_nothrow_constructor</code>),
the library guarantees <code class="computeroutput">variant</code> will use only single
storage and in-place construction for <span class="emphasis"><em>every</em></span>
bounded type in the <code class="computeroutput">variant</code>. Note, however, that in
the event of assignment failure, an unspecified nothrow
default-constructible bounded type will be default-constructed in
the left-hand side operand so as to preserve the never-empty
guarantee.</li>
</ul></div>
<p>
</p>
<p><span class="bold"><strong>Implementation Note</strong></span>: So as to make
the behavior of <code class="computeroutput">variant</code> more predictable in the aftermath
of an exception, the current implementation prefers to default-construct
<code class="computeroutput">boost::blank</code> if specified as a
bounded type instead of other nothrow default-constructible bounded
types. (If this is deemed to be a useful feature, it will become part
of the specification for <code class="computeroutput">variant</code>; otherwise, it may be
obsoleted. Please provide feedback to the Boost mailing list.)</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.design.never-empty.roadmap"></a>Future Direction: Policy-based Implementation</h4></div></div></div>
<p>As the previous sections have demonstrated, much effort has been
expended in an attempt to provide a balance between performance, data
size, and heap usage. Further, significant optimizations may be
enabled in <code class="computeroutput">variant</code> on the basis of certain traits of its
bounded types.</p>
<p>However, there will be some users for whom the chosen compromise
is unsatisfactory (e.g.: heap allocation must be avoided at all costs;
if heap allocation is used, custom allocators must be used; etc.). For
this reason, a future version of the library will support a
policy-based implementation of <code class="computeroutput">variant</code>. While this will
not eliminate the problems described in the previous sections, it will
allow the decisions regarding tradeoffs to be decided by the user
rather than the library designers.</p>
</div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2002, 2003 Eric Friedman, Itay Maman<br>Copyright © 2014-2021 Antony Polukhin<p>Distributed under the Boost Software License, Version 1.0.
(See accompanying file <code class="filename">LICENSE_1_0.txt</code> or copy at
<a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../boost/visitor_ptr.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="misc.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

273
doc/html/variant/misc.html Normal file
View File

@@ -0,0 +1,273 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Miscellaneous Notes</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../variant.html" title="Chapter 46. Boost.Variant">
<link rel="prev" href="design.html" title="Design Overview">
<link rel="next" href="refs.html" title="References">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="design.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="refs.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="variant.misc"></a>Miscellaneous Notes</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="misc.html#variant.versus-any">Boost.Variant vs. Boost.Any</a></span></dt>
<dt><span class="section"><a href="misc.html#id-1.3.47.7.3">Portability</a></span></dt>
<dt><span class="section"><a href="misc.html#variant.troubleshooting">Troubleshooting</a></span></dt>
<dt><span class="section"><a href="misc.html#variant.ack">Acknowledgments</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="variant.versus-any"></a>Boost.Variant vs. Boost.Any</h3></div></div></div>
<p>As a discriminated union container, the Variant library shares many
of the same features of the <a class="link" href="../any.html" title="Chapter 4. Boost.Any">Any</a> library.
However, since neither library wholly encapsulates the features of the
other, one library cannot be generally recommended for use over the
other.</p>
<p>That said, Boost.Variant has several advantages over Boost.Any,
such as:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">Boost.Variant guarantees the type of its content is one of a
finite, user-specified set of types.</li>
<li class="listitem">Boost.Variant provides <span class="emphasis"><em>compile-time</em></span>
checked visitation of its content. (By contrast, the current version
of Boost.Any provides no visitation mechanism at all; but even if it
did, it would need to be checked at run-time.)</li>
<li class="listitem">Boost.Variant enables generic visitation of its content.
(Even if Boost.Any did provide a visitation mechanism, it would enable
visitation only of explicitly-specified types.)</li>
<li class="listitem">Boost.Variant offers an efficient, stack-based storage scheme
(avoiding the overhead of dynamic allocation).</li>
</ul></div>
<p>
</p>
<p>Of course, Boost.Any has several advantages over Boost.Variant,
such as:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">Boost.Any, as its name implies, allows virtually any type for
its content, providing great flexibility.</li>
<li class="listitem">Boost.Any provides the no-throw guarantee of exception safety
for its swap operation.</li>
<li class="listitem">Boost.Any makes little use of template metaprogramming
techniques (avoiding potentially hard-to-read error messages and
significant compile-time processor and memory demands).</li>
</ul></div>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="id-1.3.47.7.3"></a>Portability</h3></div></div></div>
<p>The library aims for 100% ANSI/ISO C++ conformance. However, this is
strictly impossible due to the inherently non-portable nature of the
Type Traits library's
<code class="computeroutput">type_with_alignment</code> facility. In
practice though, no compilers or platforms have been discovered where this
reliance on undefined behavior has been an issue.</p>
<p>Additionally, significant effort has been expended to ensure proper
functioning despite various compiler bugs and other conformance problems.
To date the library testsuite has
been compiled and tested successfully on at least the following compilers
for basic and advanced functionality:
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th> </th>
<th>Basic</th>
<th>
<code class="computeroutput">variant&lt;T&amp;&gt;</code>
</th>
<th>
<a class="link" href="tutorial.html#variant.tutorial.over-sequence" title="Using a type sequence to specify bounded types">
<code class="computeroutput">make_variant_over</code>
</a>
</th>
<th>
<a class="link" href="tutorial.html#variant.tutorial.recursive.recursive-variant" title="Recursive types with make_recursive_variant">
<code class="computeroutput">make_recursive_variant</code>
</a>
</th>
</tr></thead>
<tbody>
<tr>
<td>Borland C++ 5.5.1 and 5.6.4</td>
<td>X</td>
<td>X</td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>Comeau C++ 4.3.0</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
</tr>
<tr>
<td>GNU GCC 3.3.1</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
</tr>
<tr>
<td>GNU GCC 2.95.3</td>
<td>X</td>
<td>X</td>
<td> </td>
<td>X</td>
</tr>
<tr>
<td>Intel C++ 7.0</td>
<td>X</td>
<td> </td>
<td>X</td>
<td>X</td>
</tr>
<tr>
<td>Metrowerks CodeWarrior 8.3</td>
<td>X</td>
<td> </td>
<td>X</td>
<td>X</td>
</tr>
<tr>
<td>Microsoft Visual C++ 7.1</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
</tr>
<tr>
<td>Microsoft Visual C++ 6 SP5 and 7</td>
<td>X</td>
<td> </td>
<td> </td>
<td> </td>
</tr>
</tbody>
</table></div>
<p>
</p>
<p>Finally, the current state of the testsuite in CVS may be found on the
<a href="http://boost.sourceforge.net/regression-logs" target="_top">Test Summary</a>
page. Please note, however, that this page reports on day-to-day changes
to inter-release code found in the Boost CVS and thus likely does not
match the state of code found in Boost releases.</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="variant.troubleshooting"></a>Troubleshooting</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="misc.html#variant.troubleshooting.template-depth">"Template instantiation depth exceeds maximum"</a></span></dt>
<dt><span class="section"><a href="misc.html#variant.troubleshooting.compiler-memory">"Internal heap limit reached"</a></span></dt>
</dl></div>
<p>Due to the heavy use of templates in the implementation of
<code class="computeroutput">variant</code>, it is not uncommon when compiling to encounter
problems related to template instantiaton depth, compiler memory, etc. This
section attempts to provide advice to common problems experienced on several
popular compilers.</p>
<p>(This section is still in progress, with additional advice/feedback
welcome. Please post to the Boost-Users list with any useful experiences you
may have.)</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.troubleshooting.template-depth"></a>"Template instantiation depth exceeds maximum"</h4></div></div></div>
<div class="toc"><dl class="toc"><dt><span class="section"><a href="misc.html#variant.troubleshooting.template-depth.gcc">GNU GCC</a></span></dt></dl></div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="variant.troubleshooting.template-depth.gcc"></a>GNU GCC</h5></div></div></div>
<p>The compiler option
<code class="computeroutput">-ftemplate-depth-<span class="emphasis"><em>NN</em></span></code> can increase the
maximum allowed instantiation depth. (Try
<code class="computeroutput">-ftemplate-depth-50</code>.)</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.troubleshooting.compiler-memory"></a>"Internal heap limit reached"</h4></div></div></div>
<div class="toc"><dl class="toc"><dt><span class="section"><a href="misc.html#variant.troubleshooting.compiler-memory.msvc">Microsoft Visual C++</a></span></dt></dl></div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="variant.troubleshooting.compiler-memory.msvc"></a>Microsoft Visual C++</h5></div></div></div>
<p>The compiler option <code class="computeroutput">/Zm<span class="emphasis"><em>NNN</em></span></code> can
increase the memory allocation limit. The <code class="computeroutput">NNN</code> is a
scaling percentage (i.e., <code class="computeroutput">100</code> denotes the default limit).
(Try <code class="computeroutput">/Zm200</code>.)</p>
</div>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="variant.ack"></a>Acknowledgments</h3></div></div></div>
<p>Eric Friedman and Itay Maman designed the initial submission; Eric was
the primary implementer.</p>
<p>Eric is also the library maintainer and has expanded upon the initial
submission -- adding
<code class="computeroutput"><a class="link" href="../boost/make_recursive_variant.html" title="Class template make_recursive_variant">make_recursive_variant</a></code>,
<code class="computeroutput"><a class="link" href="../boost/make_variant_over.html" title="Class template make_variant_over">make_variant_over</a></code>, support for
reference content, etc.</p>
<p>Andrei Alexandrescu's work in
[<a class="link" href="refs.html#variant.refs.ale01a">Ale01a</a>]
and
[<a class="link" href="refs.html#variant.refs.ale02">Ale02</a>]
inspired the library's design.</p>
<p>Jeff Garland was the formal review manager.</p>
<p>Douglas Gregor,
Dave Abrahams,
Anthony Williams,
Fernando Cacciola,
Joel de Guzman,
Dirk Schreib,
Brad King,
Giovanni Bajo,
Eugene Gladyshev,
and others provided helpful feedback and suggestions to refine the semantics,
interface, and implementation of the library.</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2002, 2003 Eric Friedman, Itay Maman<br>Copyright © 2014-2021 Antony Polukhin<p>Distributed under the Boost Software License, Version 1.0.
(See accompanying file <code class="filename">LICENSE_1_0.txt</code> or copy at
<a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="design.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="refs.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,437 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Reference</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../variant.html" title="Chapter 46. Boost.Variant">
<link rel="prev" href="tutorial.html" title="Tutorial">
<link rel="next" href="../BOOST_VARIANT_LIMIT_TYPES.html" title="Macro BOOST_VARIANT_LIMIT_TYPES">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial.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="../BOOST_VARIANT_LIMIT_TYPES.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="variant.reference"></a>Reference</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="reference.html#variant.concepts">Concepts</a></span></dt>
<dt><span class="section"><a href="reference.html#header.boost.variant_hpp">Header &lt;boost/variant.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="reference.html#header.boost.variant.variant_fwd_hpp">Header &lt;boost/variant/variant_fwd.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="reference.html#header.boost.variant.variant_hpp">Header &lt;boost/variant/variant.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="reference.html#header.boost.variant.recursive_variant_hpp">Header &lt;boost/variant/recursive_variant.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="reference.html#header.boost.variant.recursive_wrapper_hpp">Header &lt;boost/variant/recursive_wrapper.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="reference.html#header.boost.variant.apply_visitor_hpp">Header &lt;boost/variant/apply_visitor.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="reference.html#header.boost.variant.multivisitors_hpp">Header &lt;boost/variant/multivisitors.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="reference.html#header.boost.variant.get_hpp">Header &lt;boost/variant/get.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="reference.html#header.boost.variant.polymorphic_get_hpp">Header &lt;boost/variant/polymorphic_get.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="reference.html#header.boost.variant.bad_visit_hpp">Header &lt;boost/variant/bad_visit.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="reference.html#header.boost.variant.static_visitor_hpp">Header &lt;boost/variant/static_visitor.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="reference.html#header.boost.variant.visitor_ptr_hpp">Header &lt;boost/variant/visitor_ptr.hpp&gt;</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="variant.concepts"></a>Concepts</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="reference.html#variant.concepts.bounded-type"><span class="emphasis"><em>BoundedType</em></span></a></span></dt>
<dt><span class="section"><a href="reference.html#variant.concepts.static-visitor"><span class="emphasis"><em>StaticVisitor</em></span></a></span></dt>
<dt><span class="section"><a href="reference.html#variant.concepts.output-streamable"><span class="emphasis"><em>OutputStreamable</em></span></a></span></dt>
<dt><span class="section"><a href="reference.html#variant.concepts.hashable"><span class="emphasis"><em>Hashable</em></span></a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.concepts.bounded-type"></a><span class="emphasis"><em>BoundedType</em></span>
</h4></div></div></div>
<p>The requirements on a <span class="bold"><strong>bounded type</strong></span>
are as follows:</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<a class="link" href="../CopyConstructible.html" title="Concept CopyConstructible">CopyConstructible</a> or MoveConstructible.</li>
<li class="listitem">Destructor upholds the no-throw exception-safety
guarantee.</li>
<li class="listitem">Complete at the point of <code class="computeroutput">variant</code> template
instantiation. (See
<code class="computeroutput"><a class="link" href="../boost/recursive_wrapper.html" title="Class template recursive_wrapper">boost::recursive_wrapper</a>&lt;T&gt;</code>
for a type wrapper that accepts incomplete types to enable recursive
<code class="computeroutput">variant</code> types.)</li>
</ul></div>
<p>Every type specified as a template argument to
<code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">variant</a></code> must at minimum fulfill the
above requirements. In addition, certain features of <code class="computeroutput">variant</code>
are available only if its bounded types meet the requirements of these
following additional concepts:</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<a class="link" href="../Assignable.html" title="Concept Assignable">Assignable</a>:
<code class="computeroutput">variant</code> is itself <span class="emphasis"><em>Assignable</em></span> if and
only if every one of its bounded types meets the requirements of the
concept. (Note that top-level <code class="computeroutput">const</code>-qualified types and
reference types do <span class="emphasis"><em>not</em></span> meet these
requirements.)</li>
<li class="listitem">MoveAssignable:
<code class="computeroutput">variant</code> is itself <span class="emphasis"><em>MoveAssignable</em></span> if and
only if every one of its bounded types meets the requirements of the
concept. (Note that top-level <code class="computeroutput">const</code>-qualified types and
reference types do <span class="emphasis"><em>not</em></span> meet these
requirements.)</li>
<li class="listitem">
<a class="link" href="../DefaultConstructible.html" title="Concept DefaultConstructible">DefaultConstructible</a> [20.1.4]:
<code class="computeroutput">variant</code> is itself
<a class="link" href="../DefaultConstructible.html" title="Concept DefaultConstructible">DefaultConstructible</a> if and only if its first
bounded type (i.e., <code class="computeroutput">T1</code>) meets the requirements of the
concept.</li>
<li class="listitem">
<a class="link" href="../EqualityComparable.html" title="Concept EqualityComparable">EqualityComparable</a>:
<code class="computeroutput">variant</code> is itself <a class="link" href="../EqualityComparable.html" title="Concept EqualityComparable">EqualityComparable</a>
if and only if every one of its bounded types meets the requirements
of the concept.</li>
<li class="listitem">
<a class="link" href="../LessThanComparable.html" title="Concept LessThanComparable">LessThanComparable</a>:
<code class="computeroutput">variant</code> is itself <a class="link" href="../LessThanComparable.html" title="Concept LessThanComparable">LessThanComparable</a>
if and only if every one of its bounded types meets the requirements
of the concept.</li>
<li class="listitem">
<a class="link" href="reference.html#variant.concepts.output-streamable" title="OutputStreamable"><span class="emphasis"><em>OutputStreamable</em></span></a>:
<code class="computeroutput">variant</code> is itself <span class="emphasis"><em>OutputStreamable</em></span>
if and only if every one of its bounded types meets the requirements
of the concept.</li>
<li class="listitem">
<a class="link" href="reference.html#variant.concepts.hashable" title="Hashable"><span class="emphasis"><em>Hashable</em></span></a>:
<code class="computeroutput">variant</code> is itself <span class="emphasis"><em>Hashable</em></span>
if and only if every one of its bounded types meets the requirements
of the concept.</li>
</ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.concepts.static-visitor"></a><span class="emphasis"><em>StaticVisitor</em></span>
</h4></div></div></div>
<div class="toc"><dl class="toc"><dt><span class="section"><a href="reference.html#variant.concepts.static-visitor.examples">Examples</a></span></dt></dl></div>
<p>The requirements on a <span class="bold"><strong>static
visitor</strong></span> of a type <code class="computeroutput">T</code> are as follows:</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">Must allow invocation as a function by overloading
<code class="computeroutput">operator()</code>, unambiguously accepting any value of type
<code class="computeroutput">T</code>.</li>
<li class="listitem">Must expose inner type <code class="computeroutput">result_type</code>. C++14 compatible compilers
could detect <code class="computeroutput">result_type</code> automatically, but will stick to
<code class="computeroutput">result_type</code> if it is defined. (See
<code class="computeroutput"><a class="link" href="../boost/visitor_ptr.html" title="Function template visitor_ptr">boost::visitor_ptr</a></code> for a
solution to using functions as visitors.)</li>
<li class="listitem">If <code class="computeroutput">result_type</code> is not <code class="computeroutput">void</code>, then
each operation of the function object must return a value implicitly
convertible to <code class="computeroutput">result_type</code>.</li>
</ul></div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="variant.concepts.static-visitor.examples"></a>Examples</h5></div></div></div>
<p>The following class satisfies the requirements of a static visitor
of several types (i.e., explicitly: <code class="computeroutput">int</code> and
<code class="computeroutput">std::string</code>; or, e.g., implicitly: <code class="computeroutput">short</code> and
<code class="computeroutput">const char *</code>; etc.):</p>
<pre class="programlisting">class my_visitor
: public <code class="computeroutput"><a class="link" href="../boost/static_visitor.html" title="Class template static_visitor">boost::static_visitor</a></code>&lt;int&gt;
{
public:
int operator()(int i)
{
return i * 2;
}
int operator()(const std::string&amp; s)
{
return s.length();
}
};</pre>
<p>Another example is the following class, whose function-call
operator is a member template, allowing it to operate on values of many
types. Thus, the following class is a visitor of any type that supports
streaming output (e.g., <code class="computeroutput">int</code>, <code class="computeroutput">double</code>,
<code class="computeroutput">std::string</code>, etc.):</p>
<pre class="programlisting">class printer
: public <code class="computeroutput"><a class="link" href="../boost/static_visitor.html" title="Class template static_visitor">boost::static_visitor</a></code>&lt;&gt;
{
template &lt;typename T&gt;
void operator()(const T&amp; t)
{
std::cout &lt;&lt; t &lt;&lt; std::endl;
}
};</pre>
<p>C++14 compatible compilers detect <code class="computeroutput">result_type</code> automatically:</p>
<pre class="programlisting">
<code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt;int, float&gt; v;
// ...
<code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>(
[](auto val) { return std::to_string(val); },
v
);
</pre>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.concepts.output-streamable"></a><span class="emphasis"><em>OutputStreamable</em></span>
</h4></div></div></div>
<p>The requirements on an <span class="bold"><strong>output
streamable</strong></span> type <code class="computeroutput">T</code> are as follows:</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">For any object <code class="computeroutput">t</code> of type <code class="computeroutput">T</code>,
<code class="computeroutput">std::cout &lt;&lt; t</code> must be a valid
expression.</li></ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.concepts.hashable"></a><span class="emphasis"><em>Hashable</em></span>
</h4></div></div></div>
<p>The requirements on an <span class="bold"><strong>hashable</strong></span> type <code class="computeroutput">T</code> are as follows:</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">For any object <code class="computeroutput">t</code> of type <code class="computeroutput">T</code>,
<code class="computeroutput">boost::hash&lt;T&gt;()(t)</code> must be a valid
expression.</li></ul></div>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="header.boost.variant_hpp"></a>Header &lt;<a href="../../../boost/variant.hpp" target="_top">boost/variant.hpp</a>&gt;</h3></div></div></div>
<div class="toc"><dl class="toc"><dt><span class="section"><a href="reference.html#variant.header.include-all"></a></span></dt></dl></div>
<div class="section">
<div class="titlepage"></div>
<p>This header exists simply as a convenience to the user, including
all of the headers in the <code class="computeroutput">boost/variant</code> directory except &lt;boost/multivisiors.hpp&gt;.</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="header.boost.variant.variant_fwd_hpp"></a>Header &lt;<a href="../../../boost/variant/variant_fwd.hpp" target="_top">boost/variant/variant_fwd.hpp</a>&gt;</h3></div></div></div>
<p>Provides forward declarations of the
<code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>,
<code class="computeroutput"><a class="link" href="../boost/make_variant_over.html" title="Class template make_variant_over">boost::make_variant_over</a></code>,
<code class="computeroutput"><a class="link" href="../boost/make_recursive_variant.html" title="Class template make_recursive_variant">boost::make_recursive_variant</a></code>, and
<code class="computeroutput"><a class="link" href="../boost/make_recurs_1_3_47_5_5_1_3.html" title="Class template make_recursive_variant_over">boost::make_recursive_variant_over</a></code>
class templates and the <code class="computeroutput">boost::recursive_variant_</code> tag type.
Also defines several preprocessor symbols, as described below.</p>
<pre class="synopsis">
<a class="link" href="../BOOST_VARIANT_LIMIT_TYPES.html" title="Macro BOOST_VARIANT_LIMIT_TYPES">BOOST_VARIANT_LIMIT_TYPES</a>
<a class="link" href="../BOOST_VARIANT_1_3_47_5_3_4.html" title="Macro BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES">BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES</a>
<a class="link" href="../BOOST_VARIANT_ENUM_PARAMS.html" title="Macro BOOST_VARIANT_ENUM_PARAMS">BOOST_VARIANT_ENUM_PARAMS</a>(param)
<a class="link" href="../BOOST_VARIANT_1_3_47_5_3_6.html" title="Macro BOOST_VARIANT_ENUM_SHIFTED_PARAMS">BOOST_VARIANT_ENUM_SHIFTED_PARAMS</a>(param)
<a class="link" href="../BOOST_VARIANT_1_3_47_5_3_7.html" title="Macro BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT">BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT</a>
<a class="link" href="../BOOST_VARIANT_1_3_47_5_3_8.html" title="Macro BOOST_VARIANT_DO_NOT_SPECIALIZE_STD_HASH">BOOST_VARIANT_DO_NOT_SPECIALIZE_STD_HASH</a>
<a class="link" href="../BOOST_VARIANT_1_3_47_5_3_9.html" title="Macro BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT">BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT</a></pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="header.boost.variant.variant_hpp"></a>Header &lt;<a href="../../../boost/variant/variant.hpp" target="_top">boost/variant/variant.hpp</a>&gt;</h3></div></div></div>
<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2 <span class="special">=</span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span><span class="special">,</span> <span class="special">...</span><span class="special">,</span>
<span class="keyword">typename</span> TN <span class="special">=</span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span><span class="special">&gt;</span>
<span class="keyword">class</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> Sequence<span class="special">&gt;</span> <span class="keyword">class</span> <a class="link" href="../boost/make_variant_over.html" title="Class template make_variant_over">make_variant_over</a><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="keyword">void</span> <a class="link" href="../boost/swap_1_3_47_5_4_1_2.html" title="Function template swap"><span class="identifier">swap</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">,</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> ElemType<span class="special">,</span> <span class="keyword">typename</span> Traits<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span>
<span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">ElemType</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">&gt;</span> <span class="special">&amp;</span>
<a class="link" href="../boost/operator_1_3_47_5_4_1_3.html" title="Function template operator&lt;&lt;"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></a><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">ElemType</span><span class="special">,</span><span class="identifier">Traits</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">,</span>
<span class="keyword">const</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <a class="link" href="../boost/hash_value_1_3_47_5_4_1_4.html" title="Function template hash_value"><span class="identifier">hash_value</span></a><span class="special">(</span><span class="keyword">const</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="special">}</span></pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="header.boost.variant.recursive_variant_hpp"></a>Header &lt;<a href="../../../boost/variant/recursive_variant.hpp" target="_top">boost/variant/recursive_variant.hpp</a>&gt;</h3></div></div></div>
<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">typedef</span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.recursive_variant_"></a><span class="identifier">recursive_variant_</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2 <span class="special">=</span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span><span class="special">,</span> <span class="special">...</span><span class="special">,</span>
<span class="keyword">typename</span> TN <span class="special">=</span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span><span class="special">&gt;</span>
<span class="keyword">class</span> <a class="link" href="../boost/make_recursive_variant.html" title="Class template make_recursive_variant">make_recursive_variant</a><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> Sequence<span class="special">&gt;</span> <span class="keyword">class</span> <a class="link" href="../boost/make_recurs_1_3_47_5_5_1_3.html" title="Class template make_recursive_variant_over">make_recursive_variant_over</a><span class="special">;</span>
<span class="special">}</span></pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="header.boost.variant.recursive_wrapper_hpp"></a>Header &lt;<a href="../../../boost/variant/recursive_wrapper.hpp" target="_top">boost/variant/recursive_wrapper.hpp</a>&gt;</h3></div></div></div>
<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> T<span class="special">&gt;</span> <span class="keyword">class</span> <a class="link" href="../boost/recursive_wrapper.html" title="Class template recursive_wrapper">recursive_wrapper</a><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> T<span class="special">&gt;</span> <span class="keyword">class</span> <a class="link" href="../boost/is_recursive_wrapper.html" title="Class template is_recursive_wrapper">is_recursive_wrapper</a><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> T<span class="special">&gt;</span> <span class="keyword">class</span> <a class="link" href="../boost/unwrap_recursive_wrapper.html" title="Class template unwrap_recursive_wrapper">unwrap_recursive_wrapper</a><span class="special">;</span>
<span class="special">}</span></pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="header.boost.variant.apply_visitor_hpp"></a>Header &lt;<a href="../../../boost/variant/apply_visitor.hpp" target="_top">boost/variant/apply_visitor.hpp</a>&gt;</h3></div></div></div>
<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> Visitor<span class="special">&gt;</span> <span class="keyword">class</span> <a class="link" href="../boost/apply_visitor_delayed_t.html" title="Class template apply_visitor_delayed_t">apply_visitor_delayed_t</a><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> Visitor<span class="special">&gt;</span> <span class="keyword">class</span> <a class="link" href="../boost/apply_visit_1_3_47_5_7_1_2.html" title="Class template apply_visitor_delayed_cpp14_t">apply_visitor_delayed_cpp14_t</a><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> Visitor<span class="special">,</span> <span class="keyword">typename</span> Variant<span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">Visitor</span><span class="special">::</span><span class="identifier">result_type</span> <a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor"><span class="identifier">apply_visitor</span></a><span class="special">(</span><span class="identifier">Visitor</span> <span class="special">&amp;</span><span class="special">,</span> <span class="identifier">Variant</span><span class="special">&amp;&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> Visitor<span class="special">,</span> <span class="keyword">typename</span> Variant<span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">Visitor</span><span class="special">::</span><span class="identifier">result_type</span> <a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor"><span class="identifier">apply_visitor</span></a><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Visitor</span> <span class="special">&amp;</span><span class="special">,</span> <span class="identifier">Variant</span><span class="special">&amp;&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> BinaryVisitor<span class="special">,</span> <span class="keyword">typename</span> Variant1<span class="special">,</span> <span class="keyword">typename</span> Variant2<span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">BinaryVisitor</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">OR</span> <span class="keyword">decltype</span><span class="special">(</span><span class="keyword">auto</span><span class="special">)</span>
<a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor"><span class="identifier">apply_visitor</span></a><span class="special">(</span><span class="identifier">BinaryVisitor</span> <span class="special">&amp;</span><span class="special">,</span> <span class="identifier">Variant1</span><span class="special">&amp;&amp;</span><span class="special">,</span> <span class="identifier">Variant2</span><span class="special">&amp;&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> BinaryVisitor<span class="special">,</span> <span class="keyword">typename</span> Variant1<span class="special">,</span> <span class="keyword">typename</span> Variant2<span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">BinaryVisitor</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">OR</span> <span class="keyword">decltype</span><span class="special">(</span><span class="keyword">auto</span><span class="special">)</span>
<a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor"><span class="identifier">apply_visitor</span></a><span class="special">(</span><span class="keyword">const</span> <span class="identifier">BinaryVisitor</span> <span class="special">&amp;</span><span class="special">,</span> <span class="identifier">Variant1</span><span class="special">&amp;&amp;</span><span class="special">,</span> <span class="identifier">Variant2</span><span class="special">&amp;&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> MultiVisitor<span class="special">,</span> <span class="keyword">typename</span> Variant1<span class="special">,</span> <span class="keyword">typename</span> Variant2<span class="special">,</span>
<span class="keyword">typename</span> Variant3<span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">MultiVisitor</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">OR</span> <span class="keyword">decltype</span><span class="special">(</span><span class="keyword">auto</span><span class="special">)</span>
<a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor"><span class="identifier">apply_visitor</span></a><span class="special">(</span><span class="identifier">MultiVisitor</span> <span class="special">&amp;</span><span class="special">,</span> <span class="identifier">Variant1</span><span class="special">&amp;&amp;</span><span class="special">,</span> <span class="identifier">Variant2</span><span class="special">&amp;&amp;</span><span class="special">,</span> <span class="identifier">Variant3</span><span class="special">&amp;&amp;</span><span class="special">,</span> <span class="special">...</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> MultiVisitor<span class="special">,</span> <span class="keyword">typename</span> Variant1<span class="special">,</span> <span class="keyword">typename</span> Variant2<span class="special">,</span>
<span class="keyword">typename</span> Variant3<span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">MultiVisitor</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">OR</span> <span class="keyword">decltype</span><span class="special">(</span><span class="keyword">auto</span><span class="special">)</span>
<a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor"><span class="identifier">apply_visitor</span></a><span class="special">(</span><span class="keyword">const</span> <span class="identifier">MultiVisitor</span> <span class="special">&amp;</span><span class="special">,</span> <span class="identifier">Variant1</span><span class="special">&amp;&amp;</span><span class="special">,</span> <span class="identifier">Variant2</span><span class="special">&amp;&amp;</span><span class="special">,</span> <span class="identifier">Variant3</span><span class="special">&amp;&amp;</span><span class="special">,</span>
<span class="special">...</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> Visitor<span class="special">&gt;</span>
<a class="link" href="../boost/apply_visitor_delayed_t.html" title="Class template apply_visitor_delayed_t">apply_visitor_delayed_t</a><span class="special">&lt;</span><span class="identifier">Visitor</span><span class="special">&gt;</span> <a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor"><span class="identifier">apply_visitor</span></a><span class="special">(</span><span class="identifier">Visitor</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> Visitor<span class="special">&gt;</span>
<a class="link" href="../boost/apply_visit_1_3_47_5_7_1_2.html" title="Class template apply_visitor_delayed_cpp14_t">apply_visitor_delayed_cpp14_t</a><span class="special">&lt;</span><span class="identifier">Visitor</span><span class="special">&gt;</span> <a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor"><span class="identifier">apply_visitor</span></a><span class="special">(</span><span class="identifier">Visitor</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="special">}</span></pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="header.boost.variant.multivisitors_hpp"></a>Header &lt;<a href="../../../boost/variant/multivisitors.hpp" target="_top">boost/variant/multivisitors.hpp</a>&gt;</h3></div></div></div>
<p>Provides declarations of <a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">apply_visitor</a> for three or more
<code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">variant</a></code> parameters.</p>
<pre class="synopsis">
<a class="link" href="../BOOST_VARAINT_1_3_47_5_8_3.html" title="Macro BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS">BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS</a></pre>
<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> MultiVisitor<span class="special">,</span> <span class="keyword">typename</span> Variant1<span class="special">,</span> <span class="keyword">typename</span> Variant2<span class="special">,</span>
<span class="keyword">typename</span> Variant3<span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">MultiVisitor</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">OR</span> <span class="keyword">decltype</span><span class="special">(</span><span class="keyword">auto</span><span class="special">)</span>
<a class="link" href="../boost/apply_visit_1_3_47_5_8_4_1.html" title="Function apply_visitor /*three or more variant parameters*/"><span class="identifier">apply_visitor</span> <span class="comment">/*three or more variant parameters*/</span></a><span class="special">(</span><span class="identifier">MultiVisitor</span> <span class="special">&amp;</span><span class="special">,</span>
<span class="identifier">Variant1</span><span class="special">&amp;&amp;</span><span class="special">,</span>
<span class="identifier">Variant2</span><span class="special">&amp;&amp;</span><span class="special">,</span>
<span class="identifier">Variant3</span><span class="special">&amp;&amp;</span><span class="special">,</span> <span class="special">...</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> MultiVisitor<span class="special">,</span> <span class="keyword">typename</span> Variant1<span class="special">,</span> <span class="keyword">typename</span> Variant2<span class="special">,</span>
<span class="keyword">typename</span> Variant3<span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">MultiVisitor</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">OR</span> <span class="keyword">decltype</span><span class="special">(</span><span class="keyword">auto</span><span class="special">)</span>
<a class="link" href="../boost/apply_visit_1_3_47_5_8_4_1.html" title="Function apply_visitor /*three or more variant parameters*/"><span class="identifier">apply_visitor</span> <span class="comment">/*three or more variant parameters*/</span></a><span class="special">(</span><span class="keyword">const</span> <span class="identifier">MultiVisitor</span> <span class="special">&amp;</span><span class="special">,</span>
<span class="identifier">Variant1</span><span class="special">&amp;&amp;</span><span class="special">,</span>
<span class="identifier">Variant2</span><span class="special">&amp;&amp;</span><span class="special">,</span>
<span class="identifier">Variant3</span><span class="special">&amp;&amp;</span><span class="special">,</span> <span class="special">...</span><span class="special">)</span><span class="special">;</span>
<span class="special">}</span></pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="header.boost.variant.get_hpp"></a>Header &lt;<a href="../../../boost/variant/get.hpp" target="_top">boost/variant/get.hpp</a>&gt;</h3></div></div></div>
<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">class</span> <a class="link" href="../boost/bad_get.html" title="Class bad_get">bad_get</a><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">*</span> <a class="link" href="../boost/relaxed_get.html" title="Function relaxed_get"><span class="identifier">relaxed_get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">*</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="keyword">const</span> <span class="identifier">U</span> <span class="special">*</span> <a class="link" href="../boost/relaxed_get.html" title="Function relaxed_get"><span class="identifier">relaxed_get</span></a><span class="special">(</span><span class="keyword">const</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">*</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">&amp;</span> <a class="link" href="../boost/relaxed_get.html" title="Function relaxed_get"><span class="identifier">relaxed_get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="keyword">const</span> <span class="identifier">U</span> <span class="special">&amp;</span> <a class="link" href="../boost/relaxed_get.html" title="Function relaxed_get"><span class="identifier">relaxed_get</span></a><span class="special">(</span><span class="keyword">const</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">&amp;&amp;</span> <a class="link" href="../boost/relaxed_get.html" title="Function relaxed_get"><span class="identifier">relaxed_get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">*</span> <a class="link" href="../boost/strict_get.html" title="Function strict_get"><span class="identifier">strict_get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">*</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="keyword">const</span> <span class="identifier">U</span> <span class="special">*</span> <a class="link" href="../boost/strict_get.html" title="Function strict_get"><span class="identifier">strict_get</span></a><span class="special">(</span><span class="keyword">const</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">*</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">&amp;</span> <a class="link" href="../boost/strict_get.html" title="Function strict_get"><span class="identifier">strict_get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="keyword">const</span> <span class="identifier">U</span> <span class="special">&amp;</span> <a class="link" href="../boost/strict_get.html" title="Function strict_get"><span class="identifier">strict_get</span></a><span class="special">(</span><span class="keyword">const</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">&amp;&amp;</span> <a class="link" href="../boost/strict_get.html" title="Function strict_get"><span class="identifier">strict_get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">*</span> <a class="link" href="../boost/get.html" title="Function get"><span class="identifier">get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">*</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="keyword">const</span> <span class="identifier">U</span> <span class="special">*</span> <a class="link" href="../boost/get.html" title="Function get"><span class="identifier">get</span></a><span class="special">(</span><span class="keyword">const</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">*</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">&amp;</span> <a class="link" href="../boost/get.html" title="Function get"><span class="identifier">get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="keyword">const</span> <span class="identifier">U</span> <span class="special">&amp;</span> <a class="link" href="../boost/get.html" title="Function get"><span class="identifier">get</span></a><span class="special">(</span><span class="keyword">const</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">&amp;&amp;</span> <a class="link" href="../boost/get.html" title="Function get"><span class="identifier">get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="special">}</span></pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="header.boost.variant.polymorphic_get_hpp"></a>Header &lt;<a href="../../../boost/variant/polymorphic_get.hpp" target="_top">boost/variant/polymorphic_get.hpp</a>&gt;</h3></div></div></div>
<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">class</span> <a class="link" href="../boost/bad_polymorphic_get.html" title="Class bad_polymorphic_get">bad_polymorphic_get</a><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">*</span> <a class="link" href="../boost/polymorphic_relaxed_get.html" title="Function polymorphic_relaxed_get"><span class="identifier">polymorphic_relaxed_get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">*</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="keyword">const</span> <span class="identifier">U</span> <span class="special">*</span> <a class="link" href="../boost/polymorphic_relaxed_get.html" title="Function polymorphic_relaxed_get"><span class="identifier">polymorphic_relaxed_get</span></a><span class="special">(</span><span class="keyword">const</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">*</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">&amp;</span> <a class="link" href="../boost/polymorphic_relaxed_get.html" title="Function polymorphic_relaxed_get"><span class="identifier">polymorphic_relaxed_get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="keyword">const</span> <span class="identifier">U</span> <span class="special">&amp;</span> <a class="link" href="../boost/polymorphic_relaxed_get.html" title="Function polymorphic_relaxed_get"><span class="identifier">polymorphic_relaxed_get</span></a><span class="special">(</span><span class="keyword">const</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">*</span> <a class="link" href="../boost/polymorphic_strict_get.html" title="Function polymorphic_strict_get"><span class="identifier">polymorphic_strict_get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">*</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="keyword">const</span> <span class="identifier">U</span> <span class="special">*</span> <a class="link" href="../boost/polymorphic_strict_get.html" title="Function polymorphic_strict_get"><span class="identifier">polymorphic_strict_get</span></a><span class="special">(</span><span class="keyword">const</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">*</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">&amp;</span> <a class="link" href="../boost/polymorphic_strict_get.html" title="Function polymorphic_strict_get"><span class="identifier">polymorphic_strict_get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="keyword">const</span> <span class="identifier">U</span> <span class="special">&amp;</span> <a class="link" href="../boost/polymorphic_strict_get.html" title="Function polymorphic_strict_get"><span class="identifier">polymorphic_strict_get</span></a><span class="special">(</span><span class="keyword">const</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">*</span> <a class="link" href="../boost/polymorphic_get.html" title="Function polymorphic_get"><span class="identifier">polymorphic_get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">*</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="keyword">const</span> <span class="identifier">U</span> <span class="special">*</span> <a class="link" href="../boost/polymorphic_get.html" title="Function polymorphic_get"><span class="identifier">polymorphic_get</span></a><span class="special">(</span><span class="keyword">const</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">*</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="identifier">U</span> <span class="special">&amp;</span> <a class="link" href="../boost/polymorphic_get.html" title="Function polymorphic_get"><span class="identifier">polymorphic_get</span></a><span class="special">(</span><a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> T1<span class="special">,</span> <span class="keyword">typename</span> T2<span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="keyword">typename</span> TN<span class="special">&gt;</span>
<span class="keyword">const</span> <span class="identifier">U</span> <span class="special">&amp;</span> <a class="link" href="../boost/polymorphic_get.html" title="Function polymorphic_get"><span class="identifier">polymorphic_get</span></a><span class="special">(</span><span class="keyword">const</span> <a class="link" href="../boost/variant.html" title="Class template variant">variant</a><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span><span class="special">,</span> <span class="identifier">TN</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">)</span><span class="special">;</span>
<span class="special">}</span></pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="header.boost.variant.bad_visit_hpp"></a>Header &lt;<a href="../../../boost/variant/bad_visit.hpp" target="_top">boost/variant/bad_visit.hpp</a>&gt;</h3></div></div></div>
<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">class</span> <a class="link" href="../boost/bad_visit.html" title="Class bad_visit">bad_visit</a><span class="special">;</span>
<span class="special">}</span></pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="header.boost.variant.static_visitor_hpp"></a>Header &lt;<a href="../../../boost/variant/static_visitor.hpp" target="_top">boost/variant/static_visitor.hpp</a>&gt;</h3></div></div></div>
<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> ResultType<span class="special">&gt;</span> <span class="keyword">class</span> <a class="link" href="../boost/static_visitor.html" title="Class template static_visitor">static_visitor</a><span class="special">;</span>
<span class="special">}</span></pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="header.boost.variant.visitor_ptr_hpp"></a>Header &lt;<a href="../../../boost/variant/visitor_ptr.hpp" target="_top">boost/variant/visitor_ptr.hpp</a>&gt;</h3></div></div></div>
<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> R<span class="special">&gt;</span> <span class="keyword">class</span> <a class="link" href="../boost/visitor_ptr_t.html" title="Class template visitor_ptr_t">visitor_ptr_t</a><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> R<span class="special">,</span> <span class="keyword">typename</span> T<span class="special">&gt;</span> <a class="link" href="../boost/visitor_ptr_t.html" title="Class template visitor_ptr_t">visitor_ptr_t</a><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">R</span><span class="special">&gt;</span> <a class="link" href="../boost/visitor_ptr.html" title="Function template visitor_ptr"><span class="identifier">visitor_ptr</span></a><span class="special">(</span><span class="identifier">R</span> <span class="special">(</span><span class="special">*</span><span class="special">)</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span><span class="special">)</span><span class="special">;</span>
<span class="special">}</span></pre>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2002, 2003 Eric Friedman, Itay Maman<br>Copyright © 2014-2021 Antony Polukhin<p>Distributed under the Boost Software License, Version 1.0.
(See accompanying file <code class="filename">LICENSE_1_0.txt</code> or copy at
<a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial.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="../BOOST_VARIANT_LIMIT_TYPES.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

147
doc/html/variant/refs.html Normal file
View File

@@ -0,0 +1,147 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>References</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../variant.html" title="Chapter 46. Boost.Variant">
<link rel="prev" href="misc.html" title="Miscellaneous Notes">
<link rel="next" href="../xpressive.html" title="Chapter 47. Boost.Xpressive">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="misc.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="../xpressive.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="variant.refs"></a>References</h2></div></div></div>
<p><a name="variant.refs.abr00"></a>
<a href="http://boost.org/more/generic_exception_safety.html" target="_top">[Abr00]</a>
David Abrahams.
"Exception-Safety in Generic Components."
M. Jazayeri, R. Loos, D. Musser (eds.):
Generic Programming '98, Proc. of a Dagstuhl Seminar, Lecture Notes on Computer Science, Vol. 1766, pp. 69-79.
Springer-Verlag Berlin Heidelberg.
2000.
</p>
<p><a name="variant.refs.abr01"></a>
<a href="http://boost.org/more/error_handling.html" target="_top">[Abr01]</a>
David Abrahams.
"Error and Exception Handling."
Boost technical article.
2001-2003.
</p>
<p><a name="variant.refs.ale01a"></a>
<a href="http://www.oonumerics.org/tmpw01/alexandrescu.pdf" target="_top">[Ale01a]</a>
Andrei Alexandrescu.
"An Implementation of Discriminated Unions in C++."
<span class="emphasis"><em>OOPSLA 2001</em></span>, Second Workshop on C++ Template Programming.
Tampa Bay, 14 October 2001.
</p>
<p><a name="variant.refs.ale01b"></a>
<a href="http://www.moderncppdesign.com/book/main.html" target="_top">[Ale01b]</a>
Andrei Alexandrescu.
<span class="emphasis"><em>Modern C++ Design</em></span>.
Addison-Wesley, C++ In-Depth series.
2001.
</p>
<p><a name="variant.refs.ale02"></a>
<a href="http://cuj.com/experts/2008/alexandr.htm" target="_top">[Ale02]</a>
Andrei Alexandrescu.
"Generic&lt;Programming&gt;: Discriminated Unions" series:
<a href="http://cuj.com/experts/2004/alexandr.htm" target="_top">Part 1</a>,
<a href="http://cuj.com/experts/2006/alexandr.htm" target="_top">Part 2</a>,
<a href="http://cuj.com/experts/2008/alexandr.htm" target="_top">Part 3</a>.
<span class="emphasis"><em>C/C++ Users Journal</em></span>.
2002.
</p>
<p><a name="variant.refs.boo02"></a>
<a href="http://lists.boost.org/MailArchives/boost/msg30415.php" target="_top">[Boo02]</a>
Various Boost members.
"Proposal --- A type-safe union."
Boost public discussion.
2002.
</p>
<p><a name="variant.refs.c++98"></a>
[C++98]
<span class="emphasis"><em>International Standard, Programming Languages C++</em></span>.
ISO/IEC:14882.
1998.
</p>
<p><a name="variant.refs.gof95"></a>
[GoF95]
Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides.
<span class="emphasis"><em>Design Patterns: Elements of Reusable Object-Oriented Software</em></span>.
Addison-Wesley.
1995.
</p>
<p><a name="variant.refs.gre02"></a>
<a href="http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?variant" target="_top">[Gre02]</a>
Douglas Gregor.
"BOOST_USER: variant."
Boost Wiki paper.
2002.
</p>
<p><a name="variant.refs.gur02"></a>
MPL
Aleksey Gurtovoy.
<span class="emphasis"><em>Boost Metaprogramming Library.</em></span>
2002.
</p>
<p><a name="variant.refs.hen01"></a>
<a class="link" href="../any.html" title="Chapter 4. Boost.Any">[Hen01]</a>
Kevlin Henney.
<span class="emphasis"><em>Boost Any Library.</em></span>
2001.
</p>
<p><a name="variant.refs.mk02"></a>
Preprocessor
Paul Mensonides and Vesa Karvonen.
<span class="emphasis"><em>Boost Preprocessor Library.</em></span>
2002.
</p>
<p><a name="variant.refs.mcd+01"></a>
Type Traits
Steve Cleary, Beman Dawes, Aleksey Gurtovoy, Howard Hinnant, Jesse Jones, Mat Marcus, John Maddock, Jeremy Siek.
<span class="emphasis"><em>Boost Type Traits Library</em></span>.
2001.
</p>
<p><a name="variant.refs.sut00"></a>
<a href="http://www.gotw.ca/publications/xc++.htm" target="_top">[Sut00]</a>
Herb Sutter.
<span class="emphasis"><em>Exceptional C++: 47 Engineering Puzzles, Programming Problems, and Solutions</em></span>.
Addison-Wesley, C++ In-Depth series.
2000.
</p>
<p><a name="variant.refs.wil02"></a>
<a href="http://aspn.activestate.com/ASPN/Mail/Message/boost/1314807" target="_top">[Wil02]</a>
Anthony Williams.
Double-Storage Proposal.
2002.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2002, 2003 Eric Friedman, Itay Maman<br>Copyright © 2014-2021 Antony Polukhin<p>Distributed under the Boost Software License, Version 1.0.
(See accompanying file <code class="filename">LICENSE_1_0.txt</code> or copy at
<a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="misc.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="../xpressive.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,669 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Tutorial</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../variant.html" title="Chapter 46. Boost.Variant">
<link rel="prev" href="../variant.html" title="Chapter 46. Boost.Variant">
<link rel="next" href="reference.html" title="Reference">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<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>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="variant.tutorial"></a>Tutorial</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="tutorial.html#variant.tutorial.basic">Basic Usage</a></span></dt>
<dt><span class="section"><a href="tutorial.html#variant.tutorial.advanced">Advanced Topics</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="variant.tutorial.basic"></a>Basic Usage</h3></div></div></div>
<p>A discriminated union container on some set of types is defined by
instantiating the <code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code> class
template with the desired types. These types are called
<span class="bold"><strong>bounded types</strong></span> and are subject to the
requirements of the
<a class="link" href="reference.html#variant.concepts.bounded-type" title="BoundedType"><span class="emphasis"><em>BoundedType</em></span></a>
concept. Any number of bounded types may be specified, up to some
implementation-defined limit (see
<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>
<p>For example, the following declares a discriminated union container on
<code class="computeroutput">int</code> and <code class="computeroutput">std::string</code>:
</p>
<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>
<p>
</p>
<p>By default, a <code class="computeroutput">variant</code> default-constructs its first
bounded type, so <code class="computeroutput">v</code> initially contains <code class="computeroutput">int(0)</code>. If
this is not desired, or if the first bounded type is not
default-constructible, a <code class="computeroutput">variant</code> can be constructed
directly from any value convertible to one of its bounded types. Similarly,
a <code class="computeroutput">variant</code> can be assigned any value convertible to one of its
bounded types, as demonstrated in the following:
</p>
<pre class="programlisting">v = "hello";</pre>
<p>
</p>
<p>Now <code class="computeroutput">v</code> contains a <code class="computeroutput">std::string</code> equal to
<code class="computeroutput">"hello"</code>. We can demonstrate this by
<span class="bold"><strong>streaming</strong></span> <code class="computeroutput">v</code> to standard
output:
</p>
<pre class="programlisting">std::cout &lt;&lt; v &lt;&lt; std::endl;</pre>
<p>
</p>
<p>Usually though, we would like to do more with the content of a
<code class="computeroutput">variant</code> than streaming. Thus, we need some way to access the
contained value. There are two ways to accomplish this:
<code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">apply_visitor</a></code>, which is safest
and very powerful, and
<code class="computeroutput"><a class="link" href="../boost/get.html" title="Function get">get</a>&lt;T&gt;</code>, which is
sometimes more convenient to use.</p>
<p>For instance, suppose we wanted to concatenate to the string contained
in <code class="computeroutput">v</code>. With <span class="bold"><strong>value retrieval</strong></span>
by <code class="computeroutput"><a class="link" href="../boost/get.html" title="Function get">get</a></code>, this may be accomplished
quite simply, as seen in the following:
</p>
<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);
str += " world! ";</pre>
<p>
</p>
<p>As desired, the <code class="computeroutput">std::string</code> contained by <code class="computeroutput">v</code> now
is equal to <code class="computeroutput">"hello world! "</code>. Again, we can demonstrate this by
streaming <code class="computeroutput">v</code> to standard output:
</p>
<pre class="programlisting">std::cout &lt;&lt; v &lt;&lt; std::endl;</pre>
<p>
</p>
<p>While use of <code class="computeroutput">get</code> is perfectly acceptable in this trivial
example, <code class="computeroutput">get</code> generally suffers from several significant
shortcomings. For instance, if we were to write a function accepting a
<code class="computeroutput">variant&lt;int, std::string&gt;</code>, we would not know whether
the passed <code class="computeroutput">variant</code> contained an <code class="computeroutput">int</code> or a
<code class="computeroutput">std::string</code>. If we insisted upon continued use of
<code class="computeroutput">get</code>, we would need to query the <code class="computeroutput">variant</code> for its
contained type. The following function, which "doubles" the
content of the given <code class="computeroutput">variant</code>, demonstrates this approach:
</p>
<pre class="programlisting">void times_two( boost::variant&lt; int, std::string &gt; &amp; operand )
{
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 ) )
*pi *= 2;
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 ) )
*pstr += *pstr;
}</pre>
<p>
</p>
<p>However, such code is quite brittle, and without careful attention will
likely lead to the introduction of subtle logical errors detectable only at
runtime. For instance, consider if we wished to extend
<code class="computeroutput">times_two</code> to operate on a <code class="computeroutput">variant</code> with additional
bounded types. Specifically, let's add
<code class="computeroutput">std::complex&lt;double&gt;</code> to the set. Clearly, we would need
to at least change the function declaration:
</p>
<pre class="programlisting">void times_two( boost::variant&lt; int, std::string, std::complex&lt;double&gt; &gt; &amp; operand )
{
// as above...?
}</pre>
<p>
</p>
<p>Of course, additional changes are required, for currently if the passed
<code class="computeroutput">variant</code> in fact contained a <code class="computeroutput">std::complex</code> value,
<code class="computeroutput">times_two</code> would silently return -- without any of the desired
side-effects and without any error. In this case, the fix is obvious. But in
more complicated programs, it could take considerable time to identify and
locate the error in the first place.</p>
<p>Thus, real-world use of <code class="computeroutput">variant</code> typically demands an access
mechanism more robust than <code class="computeroutput">get</code>. For this reason,
<code class="computeroutput">variant</code> supports compile-time checked
<span class="bold"><strong>visitation</strong></span> via
<code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">apply_visitor</a></code>. Visitation requires
that the programmer explicitly handle (or ignore) each bounded type. Failure
to do so results in a compile-time error.</p>
<p>Visitation of a <code class="computeroutput">variant</code> requires a visitor object. The
following demonstrates one such implementation of a visitor implementating
behavior identical to <code class="computeroutput">times_two</code>:
</p>
<pre class="programlisting">class times_two_visitor
: public <code class="computeroutput"><a class="link" href="../boost/static_visitor.html" title="Class template static_visitor">boost::static_visitor</a></code>&lt;&gt;
{
public:
void operator()(int &amp; i) const
{
i *= 2;
}
void operator()(std::string &amp; str) const
{
str += str;
}
};</pre>
<p>
</p>
<p>With the implementation of the above visitor, we can then apply it to
<code class="computeroutput">v</code>, as seen in the following:
</p>
<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>
<p>
</p>
<p>As expected, the content of <code class="computeroutput">v</code> is now a
<code class="computeroutput">std::string</code> equal to <code class="computeroutput">"hello world! hello world! "</code>.
(We'll skip the verification this time.)</p>
<p>In addition to enhanced robustness, visitation provides another
important advantage over <code class="computeroutput">get</code>: the ability to write generic
visitors. For instance, the following visitor will "double" the
content of <span class="emphasis"><em>any</em></span> <code class="computeroutput">variant</code> (provided its
bounded types each support operator+=):
</p>
<pre class="programlisting">class times_two_generic
: public <code class="computeroutput"><a class="link" href="../boost/static_visitor.html" title="Class template static_visitor">boost::static_visitor</a></code>&lt;&gt;
{
public:
template &lt;typename T&gt;
void operator()( T &amp; operand ) const
{
operand += operand;
}
};</pre>
<p>
</p>
<p>Again, <code class="computeroutput">apply_visitor</code> sets the wheels in motion:
</p>
<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>
<p>
</p>
<p>While the initial setup costs of visitation may exceed that required for
<code class="computeroutput">get</code>, the benefits quickly become significant. Before concluding
this section, we should explore one last benefit of visitation with
<code class="computeroutput">apply_visitor</code>:
<span class="bold"><strong>delayed visitation</strong></span>. Namely, a special form
of <code class="computeroutput">apply_visitor</code> is available that does not immediately apply
the given visitor to any <code class="computeroutput">variant</code> but rather returns a function
object that operates on any <code class="computeroutput">variant</code> given to it. This behavior
is particularly useful when operating on sequences of <code class="computeroutput">variant</code>
type, as the following demonstrates:
</p>
<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;
vec.push_back( 21 );
vec.push_back( "hello " );
times_two_generic visitor;
std::for_each(
vec.begin(), vec.end()
, <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>(visitor)
);</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="variant.tutorial.advanced"></a>Advanced Topics</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="tutorial.html#variant.tutorial.preprocessor">Preprocessor macros</a></span></dt>
<dt><span class="section"><a href="tutorial.html#variant.tutorial.over-sequence">Using a type sequence to specify bounded types</a></span></dt>
<dt><span class="section"><a href="tutorial.html#variant.tutorial.recursive">Recursive <code class="computeroutput">variant</code> types</a></span></dt>
<dt><span class="section"><a href="tutorial.html#variant.tutorial.binary-visitation">Binary visitation</a></span></dt>
<dt><span class="section"><a href="tutorial.html#variant.tutorial.multi-visitation">Multi visitation</a></span></dt>
</dl></div>
<p>This section discusses several features of the library often required
for advanced uses of <code class="computeroutput">variant</code>. Unlike in the above section, each
feature presented below is largely independent of the others. Accordingly,
this section is not necessarily intended to be read linearly or in its
entirety.</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.tutorial.preprocessor"></a>Preprocessor macros</h4></div></div></div>
<p>While the <code class="computeroutput">variant</code> class template's variadic parameter
list greatly simplifies use for specific instantiations of the template,
it significantly complicates use for generic instantiations. For instance,
while it is immediately clear how one might write a function accepting a
specific <code class="computeroutput">variant</code> instantiation, say
<code class="computeroutput">variant&lt;int, std::string&gt;</code>, it is less clear how one
might write a function accepting any given <code class="computeroutput">variant</code>.</p>
<p>Due to the lack of support for true variadic template parameter lists
in the C++98 standard, the preprocessor is needed. While the
Preprocessor library provides a general and
powerful solution, the need to repeat
<code class="computeroutput"><a class="link" href="../BOOST_VARIANT_LIMIT_TYPES.html" title="Macro BOOST_VARIANT_LIMIT_TYPES">BOOST_VARIANT_LIMIT_TYPES</a></code>
unnecessarily clutters otherwise simple code. Therefore, for common
use-cases, this library provides its own macro
<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>
<p>This macro simplifies for the user the process of declaring
<code class="computeroutput">variant</code> types in function templates or explicit partial
specializations of class templates, as shown in the following:
</p>
<pre class="programlisting">// general cases
template &lt;typename T&gt; void some_func(const T &amp;);
template &lt;typename T&gt; class some_class;
// function template overload
template &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;
void 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;);
// explicit partial specialization
template &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;
class 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>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.tutorial.over-sequence"></a>Using a type sequence to specify bounded types</h4></div></div></div>
<p>While convenient for typical uses, the <code class="computeroutput">variant</code> class
template's variadic template parameter list is limiting in two significant
dimensions. First, due to the lack of support for true variadic template
parameter lists in C++, the number of parameters must be limited to some
implementation-defined maximum (namely,
<code class="computeroutput"><a class="link" href="../BOOST_VARIANT_LIMIT_TYPES.html" title="Macro BOOST_VARIANT_LIMIT_TYPES">BOOST_VARIANT_LIMIT_TYPES</a></code>).
Second, the nature of parameter lists in general makes compile-time
manipulation of the lists excessively difficult.</p>
<p>To solve these problems,
<code class="computeroutput">make_variant_over&lt; <span class="emphasis"><em>Sequence</em></span> &gt;</code>
exposes a <code class="computeroutput">variant</code> whose bounded types are the elements of
<code class="computeroutput">Sequence</code> (where <code class="computeroutput">Sequence</code> is any type fulfilling
the requirements of MPL's
<span class="emphasis"><em>Sequence</em></span> concept). For instance,
</p>
<pre class="programlisting">typedef <code class="computeroutput">mpl::vector</code>&lt; std::string &gt; types_initial;
typedef <code class="computeroutput">mpl::push_front</code>&lt; types_initial, int &gt;::type types;
<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>
<p>
behaves equivalently to
</p>
<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>
<p>
</p>
<p><span class="bold"><strong>Portability</strong></span>: Unfortunately, due to
standard conformance issues in several compilers,
<code class="computeroutput">make_variant_over</code> is not universally available. On these
compilers the library indicates its lack of support for the syntax via the
definition of the preprocessor symbol
<code class="computeroutput"><a class="link" href="../BOOST_VARIANT_1_3_47_5_3_7.html" title="Macro BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT">BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT</a></code>.</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.tutorial.recursive"></a>Recursive <code class="computeroutput">variant</code> types</h4></div></div></div>
<div class="toc"><dl class="toc">
<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>
<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>
</dl></div>
<p>Recursive types facilitate the construction of complex semantics from
simple syntax. For instance, nearly every programmer is familiar with the
canonical definition of a linked list implementation, whose simple
definition allows sequences of unlimited length:
</p>
<pre class="programlisting">template &lt;typename T&gt;
struct list_node
{
T data;
list_node * next;
};</pre>
<p>
</p>
<p>The nature of <code class="computeroutput">variant</code> as a generic class template
unfortunately precludes the straightforward construction of recursive
<code class="computeroutput">variant</code> types. Consider the following attempt to construct
a structure for simple mathematical expressions:
</p>
<pre class="programlisting">struct add;
struct sub;
template &lt;typename OpTag&gt; struct binary_op;
typedef <code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt;
int
, binary_op&lt;add&gt;
, binary_op&lt;sub&gt;
&gt; expression;
template &lt;typename OpTag&gt;
struct binary_op
{
expression left; // <span class="emphasis"><em>variant instantiated here...</em></span>
expression right;
binary_op( const expression &amp; lhs, const expression &amp; rhs )
: left(lhs), right(rhs)
{
}
}; // <span class="emphasis"><em>...but binary_op not complete until here!</em></span></pre>
<p>
</p>
<p>While well-intentioned, the above approach will not compile because
<code class="computeroutput">binary_op</code> is still incomplete when the <code class="computeroutput">variant</code>
type <code class="computeroutput">expression</code> is instantiated. Further, the approach suffers
from a more significant logical flaw: even if C++ syntax were different
such that the above example could be made to "work,"
<code class="computeroutput">expression</code> would need to be of infinite size, which is
clearly impossible.</p>
<p>To overcome these difficulties, <code class="computeroutput">variant</code> includes special
support for the
<code class="computeroutput"><a class="link" href="../boost/recursive_wrapper.html" title="Class template recursive_wrapper">boost::recursive_wrapper</a></code> class
template, which breaks the circular dependency at the heart of these
problems. Further,
<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
a more convenient syntax for declaring recursive <code class="computeroutput">variant</code>
types. Tutorials for use of these facilities is described in
<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
<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>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="variant.tutorial.recursive.recursive-wrapper"></a>Recursive types with <code class="computeroutput">recursive_wrapper</code>
</h5></div></div></div>
<p>The following example demonstrates how <code class="computeroutput">recursive_wrapper</code>
could be used to solve the problem presented in
<a class="xref" href="tutorial.html#variant.tutorial.recursive" title="Recursive variant types">the section called “Recursive <code class="computeroutput">variant</code> types”</a>:
</p>
<pre class="programlisting">typedef <code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt;
int
, <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;
, <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;
&gt; expression;</pre>
<p>
</p>
<p>Because <code class="computeroutput">variant</code> provides special support for
<code class="computeroutput">recursive_wrapper</code>, clients may treat the resultant
<code class="computeroutput">variant</code> as though the wrapper were not present. This is seen
in the implementation of the following visitor, which calculates the value
of an <code class="computeroutput">expression</code> without any reference to
<code class="computeroutput">recursive_wrapper</code>:
</p>
<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>
{
public:
int operator()(int value) const
{
return value;
}
int operator()(const binary_op&lt;add&gt; &amp; binary) const
{
return <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>( calculator(), binary.left )
+ <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>( calculator(), binary.right );
}
int operator()(const binary_op&lt;sub&gt; &amp; binary) const
{
return <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>( calculator(), binary.left )
- <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>( calculator(), binary.right );
}
};</pre>
<p>
</p>
<p>Finally, we can demonstrate <code class="computeroutput">expression</code> in action:
</p>
<pre class="programlisting">void f()
{
// result = ((7-3)+8) = 12
expression result(
binary_op&lt;add&gt;(
binary_op&lt;sub&gt;(7,3)
, 8
)
);
assert( <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>(calculator(),result) == 12 );
}</pre>
<p>
</p>
<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>
has no empty state, which makes its move constructor not very optimal. Consider using <code class="computeroutput">std::unique_ptr</code>
or some other safe pointer for better performance on C++11 compatible compilers.</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="variant.tutorial.recursive.recursive-variant"></a>Recursive types with <code class="computeroutput">make_recursive_variant</code>
</h5></div></div></div>
<p>For some applications of recursive <code class="computeroutput">variant</code> types, a user
may be able to sacrifice the full flexibility of using
<code class="computeroutput">recursive_wrapper</code> with <code class="computeroutput">variant</code> for the following
convenient syntax:
</p>
<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;
int
, std::vector&lt; boost::recursive_variant_ &gt;
&gt;::type int_tree_t;</pre>
<p>
</p>
<p>Use of the resultant <code class="computeroutput">variant</code> type is as expected:
</p>
<pre class="programlisting">std::vector&lt; int_tree_t &gt; subresult;
subresult.push_back(3);
subresult.push_back(5);
std::vector&lt; int_tree_t &gt; result;
result.push_back(1);
result.push_back(subresult);
result.push_back(7);
int_tree_t var(result);</pre>
<p>
</p>
<p>To be clear, one might represent the resultant content of
<code class="computeroutput">var</code> as <code class="computeroutput">( 1 ( 3 5 ) 7 )</code>.</p>
<p>Finally, note that a type sequence can be used to specify the bounded
types of a recursive <code class="computeroutput">variant</code> via the use of
<code class="computeroutput"><a class="link" href="../boost/make_recurs_1_3_47_5_5_1_3.html" title="Class template make_recursive_variant_over">boost::make_recursive_variant_over</a></code>,
whose semantics are the same as <code class="computeroutput">make_variant_over</code> (which is
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>
<p><span class="bold"><strong>Portability</strong></span>: Unfortunately, due to
standard conformance issues in several compilers,
<code class="computeroutput">make_recursive_variant</code> is not universally supported. On these
compilers the library indicates its lack of support via the definition
of the preprocessor symbol
<code class="computeroutput"><a class="link" href="../BOOST_VARIANT_1_3_47_5_3_9.html" title="Macro BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT">BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT</a></code>.
Thus, unless working with highly-conformant compilers, maximum portability
will be achieved by instead using <code class="computeroutput">recursive_wrapper</code>, as
described in
<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>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.tutorial.binary-visitation"></a>Binary visitation</h4></div></div></div>
<p>As the tutorial above demonstrates, visitation is a powerful mechanism
for manipulating <code class="computeroutput">variant</code> content. Binary visitation further
extends the power and flexibility of visitation by allowing simultaneous
visitation of the content of two different <code class="computeroutput">variant</code>
objects.</p>
<p>Notably this feature requires that binary visitors are incompatible
with the visitor objects discussed in the tutorial above, as they must
operate on two arguments. The following demonstrates the implementation of
a binary visitor:
</p>
<pre class="programlisting">class are_strict_equals
: 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;
{
public:
template &lt;typename T, typename U&gt;
bool operator()( const T &amp;, const U &amp; ) const
{
return false; // cannot compare different types
}
template &lt;typename T&gt;
bool operator()( const T &amp; lhs, const T &amp; rhs ) const
{
return lhs == rhs;
}
};</pre>
<p>
</p>
<p>As expected, the visitor is applied to two <code class="computeroutput">variant</code>
arguments by means of <code class="computeroutput">apply_visitor</code>:
</p>
<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" );
<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" );
assert( <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) );
<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" );
assert( !<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>
<p>
</p>
<p>Finally, we must note that the function object returned from the
"delayed" form of
<code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">apply_visitor</a></code> also supports
binary visitation, as the following demonstrates:
</p>
<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;
std::vector&lt; my_variant &gt; seq1;
seq1.push_back("pi is close to ");
seq1.push_back(3.14);
std::list&lt; my_variant &gt; seq2;
seq2.push_back("pi is close to ");
seq2.push_back(3.14);
are_strict_equals visitor;
assert( std::equal(
seq1.begin(), seq1.end(), seq2.begin()
, <code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">boost::apply_visitor</a></code>( visitor )
) );</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="variant.tutorial.multi-visitation"></a>Multi visitation</h4></div></div></div>
<p>Multi visitation extends the power and flexibility of visitation by allowing simultaneous
visitation of the content of three and more different <code class="computeroutput">variant</code>
objects. Note that header for multi visitors shall be included separately.</p>
<p>Notably this feature requires that multi visitors are incompatible
with the visitor objects discussed in the tutorial above, as they must
operate on same amout of arguments that was passed to <code class="computeroutput">apply_visitor</code>.
The following demonstrates the implementation of a multi visitor for three parameters:
</p>
<pre class="programlisting">
#include &lt;boost/variant/multivisitors.hpp&gt;
typedef <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;
typedef <code class="computeroutput"><a class="link" href="../boost/variant.html" title="Class template variant">boost::variant</a></code>&lt;int, double&gt; arithmetics_t;
struct 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; {
template &lt;class T1, class T2&gt;
arithmetics_t operator()(bool b, T1 v1, T2 v2) const {
if (b) {
return v1;
} else {
return v2;
}
}
};
</pre>
<p>
</p>
<p>As expected, the visitor is applied to three <code class="computeroutput">variant</code>
arguments by means of <code class="computeroutput">apply_visitor</code>:
</p>
<pre class="programlisting">
bool_like_t v0(true), v1(1), v2(2.0);
assert(
<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)
==
arithmetics_t(1)
);
</pre>
<p>
</p>
<p>Finally, we must note that multi visitation does not support
"delayed" form of
<code class="computeroutput"><a class="link" href="../boost/apply_visitor.html" title="Function apply_visitor">apply_visitor</a> if
<a class="link" href="../BOOST_VARIANT_1_3_47_5_3_4.html" title="Macro BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES">BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES</a> is defined</code>.
</p>
</div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2002, 2003 Eric Friedman, Itay Maman<br>Copyright © 2014-2021 Antony Polukhin<p>Distributed under the Boost Software License, Version 1.0.
(See accompanying file <code class="filename">LICENSE_1_0.txt</code> or copy at
<a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<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>
</div>
</body>
</html>