Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/variant/doc/introduction.xml @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 5.0 KB
Line 
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
3  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
4<section id="variant.intro">
5  <title>Introduction</title>
6
7  <using-namespace name="boost"/>
8
9<section id="variant.abstract">
10  <title>Abstract</title>
11
12<para>The <code>variant</code> class template is a safe, generic, stack-based
13discriminated union container, offering a simple solution for manipulating an
14object from a heterogeneous set of types in a uniform manner. Whereas
15standard containers such as <code>std::vector</code> may be thought of as
16"<emphasis role="bold">multi-value, single type</emphasis>,"
17<code>variant</code> is "<emphasis role="bold">multi-type,
18single value</emphasis>."</para>
19
20<para>Notable features of <code><classname>boost::variant</classname></code>
21include:</para>
22
23<itemizedlist>
24  <listitem>Full value semantics, including adherence to standard
25    overload resolution rules for conversion operations.</listitem>
26  <listitem>Compile-time type-safe value visitation via
27    <code><functionname>boost::apply_visitor</functionname></code>.</listitem>
28  <listitem>Run-time checked explicit value retrieval via
29    <code><functionname>boost::get</functionname></code>.</listitem>
30  <listitem>Support for recursive variant types via both
31    <code><classname>boost::make_recursive_variant</classname></code> and
32    <code><classname>boost::recursive_wrapper</classname></code>.</listitem>
33  <listitem>Efficient implementation -- stack-based when possible (see
34    <xref linkend="variant.design.never-empty"/> for more details).</listitem>
35</itemizedlist>
36
37</section>
38
39<section id="variant.motivation">
40  <title>Motivation</title>
41
42<section id="variant.motivation.problem">
43  <title>Problem</title>
44
45<para>Many times, during the development of a C++ program, the
46programmer finds himself in need of manipulating several distinct
47types in a uniform manner. Indeed, C++ features direct language
48support for such types through its <code>union</code> 
49keyword:</para>
50
51<programlisting>union { int i; double d; } u;
52u.d = 3.14;
53u.i = 3; // overwrites u.d (OK: u.d is a POD type)</programlisting>
54
55<para>C++'s <code>union</code> construct, however, is nearly
56useless in an object-oriented environment. The construct entered
57the language primarily as a means for preserving compatibility with
58C, which supports only POD (Plain Old Data) types, and so does not
59accept types exhibiting non-trivial construction or
60destruction:</para>
61
62<programlisting>union {
63  int i;
64  std::string s; // illegal: std::string is not a POD type!
65} u;</programlisting>
66
67<para>Clearly another approach is required. Typical solutions
68feature the dynamic-allocation of objects, which are subsequently
69manipulated through a common base type (often a virtual base class
70    [<link linkend="variant.refs.hen01">Hen01</link>]
71or, more dangerously, a <code>void*</code>). Objects of
72concrete type may be then retrieved by way of a polymorphic downcast
73construct (e.g., <code>dynamic_cast</code>,
74<code><functionname>boost::any_cast</functionname></code>, etc.).</para>
75
76<para>However, solutions of this sort are highly error-prone, due
77to the following:</para>
78
79<itemizedlist>
80  <listitem><emphasis>Downcast errors cannot be detected at
81    compile-time.</emphasis> Thus, incorrect usage of downcast
82    constructs will lead to bugs detectable only at run-time.</listitem>
83  <listitem><emphasis>Addition of new concrete types may be
84    ignored.</emphasis> If a new concrete type is added to the
85    hierarchy, existing downcast code will continue to work as-is,
86    wholly ignoring the new type. Consequently, the programmer must
87    manually locate and modify code at numerous locations, which often
88    results in run-time errors that are difficult to find.</listitem>
89</itemizedlist>
90
91<para>Furthermore, even when properly implemented, these solutions tend
92to incur a relatively significant abstraction penalty due to the use of
93the heap, virtual function calls, and polymorphic downcasts.</para>
94
95</section>
96
97<section id="variant.motivation.solution">
98  <title>Solution: A Motivating Example</title>
99
100<para>The <code><classname>boost::variant</classname></code> class template
101addresses these issues in a safe, straightforward, and efficient manner. The
102following example demonstrates how the class can be used:</para>
103
104<programlisting>#include "boost/variant.hpp"
105#include &lt;iostream&gt;
106
107class my_visitor : public <classname>boost::static_visitor</classname>&lt;int&gt;
108{
109public:
110    int operator()(int i) const
111    {
112        return i;
113    }
114   
115    int operator()(const <classname>std::string</classname> &amp; str) const
116    {
117        return str.length();
118    }
119};
120
121int main()
122{
123    <classname>boost::variant</classname>&lt; int, std::string &gt; u("hello world");
124    std::cout &lt;&lt; u; // output: hello world
125
126    int result = <functionname>boost::apply_visitor</functionname>( my_visitor(), u );
127    std::cout &lt;&lt; result; // output: 11 (i.e., length of "hello world")
128}
129</programlisting>
130
131</section>
132
133</section>
134
135</section>
Note: See TracBrowser for help on using the repository browser.