• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>&lt;T&gt;</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>&lt;int&gt;
105{
106public:
107
108    int operator()(int i)
109    {
110        return i * 2;
111    }
112
113    int operator()(const std::string&amp; 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>&lt;&gt;
128{
129    template &lt;typename T&gt;
130    void operator()(const T&amp; t)
131    {
132        std::cout &lt;&lt; t &lt;&lt; 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>&lt;int, float&gt; 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 &lt;&lt; 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&lt;T&gt;()(t)</code> must be a valid
172        expression.</listitem>
173    </itemizedlist>
174  </section>
175
176</section>
177