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