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