concepts.xml 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <!DOCTYPE header 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.concepts">
  10. <title>Concepts</title>
  11. <using-namespace name="boost"/>
  12. <section id="variant.concepts.bounded-type">
  13. <title><emphasis>BoundedType</emphasis></title>
  14. <para>The requirements on a <emphasis role="bold">bounded type</emphasis>
  15. are as follows:</para>
  16. <itemizedlist>
  17. <listitem><conceptname>CopyConstructible</conceptname> or <conceptname>MoveConstructible</conceptname>.</listitem>
  18. <listitem>Destructor upholds the no-throw exception-safety
  19. guarantee.</listitem>
  20. <listitem>Complete at the point of <code>variant</code> template
  21. instantiation. (See
  22. <code><classname>boost::recursive_wrapper</classname>&lt;T&gt;</code>
  23. for a type wrapper that accepts incomplete types to enable recursive
  24. <code>variant</code> types.)</listitem>
  25. </itemizedlist>
  26. <para>Every type specified as a template argument to
  27. <code><classname>variant</classname></code> must at minimum fulfill the
  28. above requirements. In addition, certain features of <code>variant</code>
  29. are available only if its bounded types meet the requirements of these
  30. following additional concepts:</para>
  31. <itemizedlist>
  32. <listitem><conceptname>Assignable</conceptname>:
  33. <code>variant</code> is itself <emphasis>Assignable</emphasis> if and
  34. only if every one of its bounded types meets the requirements of the
  35. concept. (Note that top-level <code>const</code>-qualified types and
  36. reference types do <emphasis>not</emphasis> meet these
  37. requirements.)</listitem>
  38. <listitem><conceptname>MoveAssignable</conceptname>:
  39. <code>variant</code> is itself <emphasis>MoveAssignable</emphasis> if and
  40. only if every one of its bounded types meets the requirements of the
  41. concept. (Note that top-level <code>const</code>-qualified types and
  42. reference types do <emphasis>not</emphasis> meet these
  43. requirements.)</listitem>
  44. <listitem><conceptname>DefaultConstructible</conceptname> [20.1.4]:
  45. <code>variant</code> is itself
  46. <conceptname>DefaultConstructible</conceptname> if and only if its first
  47. bounded type (i.e., <code>T1</code>) meets the requirements of the
  48. concept.</listitem>
  49. <listitem><conceptname>EqualityComparable</conceptname>:
  50. <code>variant</code> is itself <conceptname>EqualityComparable</conceptname>
  51. if and only if every one of its bounded types meets the requirements
  52. of the concept.</listitem>
  53. <listitem><conceptname>LessThanComparable</conceptname>:
  54. <code>variant</code> is itself <conceptname>LessThanComparable</conceptname>
  55. if and only if every one of its bounded types meets the requirements
  56. of the concept.</listitem>
  57. <listitem><link linkend="variant.concepts.output-streamable"><emphasis>OutputStreamable</emphasis></link>:
  58. <code>variant</code> is itself <emphasis>OutputStreamable</emphasis>
  59. if and only if every one of its bounded types meets the requirements
  60. of the concept.</listitem>
  61. <listitem><link linkend="variant.concepts.hashable"><emphasis>Hashable</emphasis></link>:
  62. <code>variant</code> is itself <emphasis>Hashable</emphasis>
  63. if and only if every one of its bounded types meets the requirements
  64. of the concept.</listitem>
  65. </itemizedlist>
  66. </section>
  67. <section id="variant.concepts.static-visitor">
  68. <title><emphasis>StaticVisitor</emphasis></title>
  69. <para>The requirements on a <emphasis role="bold">static
  70. visitor</emphasis> of a type <code>T</code> are as follows:</para>
  71. <itemizedlist>
  72. <listitem>Must allow invocation as a function by overloading
  73. <code>operator()</code>, unambiguously accepting any value of type
  74. <code>T</code>.</listitem>
  75. <listitem>Must expose inner type <code>result_type</code>. C++14 compatible compilers
  76. could detect <code>result_type</code> automatically, but will stick to
  77. <code>result_type</code> if it is defined. (See
  78. <code><functionname>boost::visitor_ptr</functionname></code> for a
  79. solution to using functions as visitors.)</listitem>
  80. <listitem>If <code>result_type</code> is not <code>void</code>, then
  81. each operation of the function object must return a value implicitly
  82. convertible to <code>result_type</code>.</listitem>
  83. </itemizedlist>
  84. <section id="variant.concepts.static-visitor.examples">
  85. <title>Examples</title>
  86. <para>The following class satisfies the requirements of a static visitor
  87. of several types (i.e., explicitly: <code>int</code> and
  88. <code>std::string</code>; or, e.g., implicitly: <code>short</code> and
  89. <code>const char *</code>; etc.):</para>
  90. <programlisting>class my_visitor
  91. : public <classname>boost::static_visitor</classname>&lt;int&gt;
  92. {
  93. public:
  94. int operator()(int i)
  95. {
  96. return i * 2;
  97. }
  98. int operator()(const std::string&amp; s)
  99. {
  100. return s.length();
  101. }
  102. };</programlisting>
  103. <para>Another example is the following class, whose function-call
  104. operator is a member template, allowing it to operate on values of many
  105. types. Thus, the following class is a visitor of any type that supports
  106. streaming output (e.g., <code>int</code>, <code>double</code>,
  107. <code>std::string</code>, etc.):</para>
  108. <programlisting>class printer
  109. : public <classname>boost::static_visitor</classname>&lt;&gt;
  110. {
  111. template &lt;typename T&gt;
  112. void operator()(const T&amp; t)
  113. {
  114. std::cout &lt;&lt; t &lt;&lt; std::endl;
  115. }
  116. };</programlisting>
  117. <para>C++14 compatible compilers detect <code>result_type</code> automatically:</para>
  118. <programlisting>
  119. <classname>boost::variant</classname>&lt;int, float&gt; v;
  120. // ...
  121. <functionname>boost::apply_visitor</functionname>(
  122. [](auto val) { return std::to_string(val); },
  123. v
  124. );
  125. </programlisting>
  126. </section>
  127. </section>
  128. <section id="variant.concepts.output-streamable">
  129. <title><emphasis>OutputStreamable</emphasis></title>
  130. <para>The requirements on an <emphasis role="bold">output
  131. streamable</emphasis> type <code>T</code> are as follows:</para>
  132. <itemizedlist>
  133. <listitem>For any object <code>t</code> of type <code>T</code>,
  134. <code>std::cout &lt;&lt; t</code> must be a valid
  135. expression.</listitem>
  136. </itemizedlist>
  137. </section>
  138. <section id="variant.concepts.hashable">
  139. <title><emphasis>Hashable</emphasis></title>
  140. <para>The requirements on an <emphasis role="bold">hashable</emphasis> type <code>T</code> are as follows:</para>
  141. <itemizedlist>
  142. <listitem>For any object <code>t</code> of type <code>T</code>,
  143. <code>boost::hash&lt;T&gt;()(t)</code> must be a valid
  144. expression.</listitem>
  145. </itemizedlist>
  146. </section>
  147. </section>