introduction.xml 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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. <!--
  5. Copyright 2003, Eric Friedman, Itay Maman.
  6. Distributed under the Boost Software License, Version 1.0. (See accompanying
  7. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. -->
  9. <section id="variant.intro">
  10. <title>Introduction</title>
  11. <using-namespace name="boost"/>
  12. <section id="variant.abstract">
  13. <title>Abstract</title>
  14. <para>The <code>variant</code> class template is a safe, generic, stack-based
  15. discriminated union container, offering a simple solution for manipulating an
  16. object from a heterogeneous set of types in a uniform manner. Whereas
  17. standard containers such as <code>std::vector</code> may be thought of as
  18. "<emphasis role="bold">multi-value, single type</emphasis>,"
  19. <code>variant</code> is "<emphasis role="bold">multi-type,
  20. single value</emphasis>."</para>
  21. <para>Notable features of <code><classname>boost::variant</classname></code>
  22. include:</para>
  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. </section>
  37. <section id="variant.motivation">
  38. <title>Motivation</title>
  39. <section id="variant.motivation.problem">
  40. <title>Problem</title>
  41. <para>Many times, during the development of a C++ program, the
  42. programmer finds himself in need of manipulating several distinct
  43. types in a uniform manner. Indeed, C++ features direct language
  44. support for such types through its <code>union</code>
  45. keyword:</para>
  46. <programlisting>union { int i; double d; } u;
  47. u.d = 3.14;
  48. u.i = 3; // overwrites u.d (OK: u.d is a POD type)</programlisting>
  49. <para>C++'s <code>union</code> construct, however, is nearly
  50. useless in an object-oriented environment. The construct entered
  51. the language primarily as a means for preserving compatibility with
  52. C, which supports only POD (Plain Old Data) types, and so does not
  53. accept types exhibiting non-trivial construction or
  54. destruction:</para>
  55. <programlisting>union {
  56. int i;
  57. std::string s; // illegal: std::string is not a POD type!
  58. } u;</programlisting>
  59. <para>Clearly another approach is required. Typical solutions
  60. feature the dynamic-allocation of objects, which are subsequently
  61. manipulated through a common base type (often a virtual base class
  62. [<link linkend="variant.refs.hen01">Hen01</link>]
  63. or, more dangerously, a <code>void*</code>). Objects of
  64. concrete type may be then retrieved by way of a polymorphic downcast
  65. construct (e.g., <code>dynamic_cast</code>,
  66. <code><functionname>boost::any_cast</functionname></code>, etc.).</para>
  67. <para>However, solutions of this sort are highly error-prone, due
  68. to the following:</para>
  69. <itemizedlist>
  70. <listitem><emphasis>Downcast errors cannot be detected at
  71. compile-time.</emphasis> Thus, incorrect usage of downcast
  72. constructs will lead to bugs detectable only at run-time.</listitem>
  73. <listitem><emphasis>Addition of new concrete types may be
  74. ignored.</emphasis> If a new concrete type is added to the
  75. hierarchy, existing downcast code will continue to work as-is,
  76. wholly ignoring the new type. Consequently, the programmer must
  77. manually locate and modify code at numerous locations, which often
  78. results in run-time errors that are difficult to find.</listitem>
  79. </itemizedlist>
  80. <para>Furthermore, even when properly implemented, these solutions tend
  81. to incur a relatively significant abstraction penalty due to the use of
  82. the heap, virtual function calls, and polymorphic downcasts.</para>
  83. </section>
  84. <section id="variant.motivation.solution">
  85. <title>Solution: A Motivating Example</title>
  86. <para>The <code><classname>boost::variant</classname></code> class template
  87. addresses these issues in a safe, straightforward, and efficient manner. The
  88. following example demonstrates how the class can be used:</para>
  89. <programlisting>#include "boost/variant.hpp"
  90. #include &lt;iostream&gt;
  91. class my_visitor : public <classname>boost::static_visitor</classname>&lt;int&gt;
  92. {
  93. public:
  94. int operator()(int i) const
  95. {
  96. return i;
  97. }
  98. int operator()(const <classname>std::string</classname> &amp; str) const
  99. {
  100. return str.length();
  101. }
  102. };
  103. int main()
  104. {
  105. <classname>boost::variant</classname>&lt; int, std::string &gt; u("hello world");
  106. std::cout &lt;&lt; u; // output: hello world
  107. int result = <functionname>boost::apply_visitor</functionname>( my_visitor(), u );
  108. std::cout &lt;&lt; result; // output: 11 (i.e., length of "hello world")
  109. }
  110. </programlisting>
  111. </section>
  112. </section>
  113. </section>