mirror of
https://github.com/boostorg/variant.git
synced 2025-05-12 13:51:46 +00:00
177 lines
7.1 KiB
XML
177 lines
7.1 KiB
XML
<?xml version="1.0" encoding="utf-8" ?>
|
|
<!DOCTYPE header PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
|
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
|
<!--
|
|
Copyright 2003, Eric Friedman, Itay Maman.
|
|
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
-->
|
|
<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> or <conceptname>MoveConstructible</conceptname>.</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>MoveAssignable</conceptname>:
|
|
<code>variant</code> is itself <emphasis>MoveAssignable</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>
|
|
<listitem><link linkend="variant.concepts.hashable"><emphasis>Hashable</emphasis></link>:
|
|
<code>variant</code> is itself <emphasis>Hashable</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>. C++14 compatible compilers
|
|
could detect <code>result_type</code> automatically, but will stick to
|
|
<code>result_type</code> if it is defined. (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>
|
|
|
|
<para>C++14 compatible compilers detect <code>result_type</code> automatically:</para>
|
|
|
|
<programlisting>
|
|
<classname>boost::variant</classname><int, float> v;
|
|
// ...
|
|
|
|
<functionname>boost::apply_visitor</functionname>(
|
|
[](auto val) { return std::to_string(val); },
|
|
v
|
|
);
|
|
</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 id="variant.concepts.hashable">
|
|
<title><emphasis>Hashable</emphasis></title>
|
|
|
|
<para>The requirements on an <emphasis role="bold">hashable</emphasis> type <code>T</code> are as follows:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>For any object <code>t</code> of type <code>T</code>,
|
|
<code>boost::hash<T>()(t)</code> must be a valid
|
|
expression.</listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
|
|
</section>
|