<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="author" content="P0088R1, ISO/IEC JTC1 SC22 WG21">

<link rel="stylesheet" href="http://cdn.jsdelivr.net/font-hack/2.015/css/hack.min.css"/>
<style type="text/css">
pre {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  margin-left:20pt;
  line-height: 1.1em;
  font-size: small;
}
code {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-size: small;
}
pre > i {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > i {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
pre > em {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > em {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
body {
    color: #000000; background-color: #FFFFFF; 
    font-family: "Book Antiqua", "Times New Roman", "Times", serif;
    padding: 2em;
}
/*del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }*/
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: none;
    border-bottom: 1px solid #005100;
    color: #005100;
    line-height: 1.4em;
}
span.section_name {
    float: right;
    font-weight: bold;
}

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }

p.function { }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; margin-bottom: 0.5em;}

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5empadding-right: 0.5em; ; }

blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto; }

table.header {
  margin-left: 0em;
  border: none;
    margin-bottom: 2em;
}
th { text-align: left; vertical-align: top;
  padding-left: 0.4em; 
  padding-right: 0.4em; }
td { text-align: left; vertical-align: top;
  padding-left: 0.4em; 
  padding-right: 0.4em;  }
</style>

<title>Variant: a type-safe union (v6).</title>
</head>

<body>
<table class="header">
    <tr><td>Document Number:</td> <td>P0088R1, ISO/IEC JTC1 SC22 WG21</td></tr>
  <tr><td>Audience:</td><td>LWG</td></tr>
    <tr><td>Date:</td><td>2016-02-13</td></tr>
    <tr><td>Author:</td><td>Axel Naumann (axel@cern.ch)</td></tr>
</table>
<h1>Variant: a type-safe union (v6).</h1>

    <h2>Table of Contents</h2>
<nav id="TOC">
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#discussion">Discussion</a></li>
<li><a href="#proposed-wording">Proposed wording</a></li>
<li><a href="#acknowledgments">Acknowledgments</a></li>
<li><a href="#references">References</a></li>
</ul>
</nav>

    <h2>&nbsp;</h2>
<blockquote>
<p>Variant is the very spice of life,<br />
 That gives it all its flavor.<br />
 <em>- William Cowper's "The Task", or actually a variant thereof</em></p>
</blockquote>

<h2 id="introduction">Introduction</h2>
<p>C++ needs a type-safe union; here is a proposal. It attempts to apply the lessons learned from <code>optional</code> <span class="citation" data-cites="N4335">(1)</span>. It behaves as below:</p>

<pre><code>
variant&lt;int, float&gt; v, w;
v = 12;
int i = get&lt;int&gt;(v);
w = get&lt;int&gt;(v);
w = get&lt;0&gt;(v); // same effect as the previous line
w = v; // same effect as the previous line

get&lt;double&gt;(v); // ill formed
get&lt;3&gt;(v); // ill formed

try {
  get&lt;float&gt;(w); // will throw.
}
catch (bad_variant_access&amp;) {}
</code></pre>

<h3 id="results-of-the-lewg-review-in-urbana">Results of the LEWG review in Urbana</h3>
<p>The LEWG review in Urbana resulted in the following straw polls that motivated changes in this revision of the paper:</p>
<ul>
<li>Should we use a <code>tuple</code>-like interface instead of the collection of <code>variant</code>-specific functions, <code>is_alternative</code> etc.? SF=8 WF=5 N=2 WA=1 SA=0</li>
<li>Consent: <code>variant</code> should be as <code>constexpr</code> as <code>std::optional</code></li>
<li>Consent: The paper should discuss the never-empty guarantee</li>
<li>Consent: Expand on <code>variant&lt;int, int&gt;</code> and <code>variant&lt;int, const int&gt;</code>.</li>
<li>Visitors are needed for the initial variant in the TS? SF=4 WF=3 N=5 WA=4 SA=0</li>
<li>Recursive variants are needed? SF=0 WF=0 N=8 WA=4 SA=2</li>
</ul>
<h3 id="results-of-the-lewg-review-in-lenexa">Results of the LEWG review in Lenexa</h3>
<p>In Lenexa, LEWG decided that <code>variant</code> should model a discriminated union.</p>
<ul>
<li>Approval votes on emptiness:</li>
<li>empty, queryable state: 12</li>
<li>invalid, assignable, UB on read: 13</li>
<li>invalid, throws on read: 6</li>
<li>double buffer: 5</li>
<li>require all members nothrow-move-constructible: 1</li>
<li>require either move-noexcept or one-default-construct-noexcept: 0</li>
<li>Want to query whether in empty state: SF=4 WF=4 N=4 WA=1 SA=1</li>
<li>Should the default constructor lead to the empty state? SF=3 WF=1 N=3 WA=1 SA=5; later SF=2 WF=0 N=2 WA=1 SA=6</li>
<li>Should the default constructor try to construct the first element? SF=5 WF=3 N=1 WA=2 SA=2, later SF=6 WF=3 N=0 WA=1 SA=1</li>
<li>Should the default constructor search for a default-constructible type and take the first possible one? (no earlier poll), later SF=0 WF=1 N=2 WA=5 SA=3</li>
<li>Remove heterogeneous assignment? SF=9 WF=5 N=3 WA=0 SA=1</li>
<li>Remove conversions, e.g. <code>variant&lt;int, string&gt; x = &quot;abc&quot;;</code>? SF=5 WF=4 N=1 WA=1 SA=0</li>
<li>Allow <code>variant&lt;string&gt; == const char *</code> and <code>variant&lt;const char *, string&gt; == const char *</code>? SF=0 WF=2 N=5 WA=3 SA=3</li>
<li>Allow <code>variant&lt;string&gt; == variant&lt;const char *&gt;</code>, and <code>variant&lt;A, B, C&gt; == variant&lt;X, Y, Z&gt;</code>? SF=0 WF=1 N=0 WA=4 SA=8</li>
<li>Allow <code>variant&lt;int, const int&gt;</code>, qualified types in general? SF=9 WF=4 N=1 WA=1 SA=1</li>
<li>Allow types to be reference types? SF=6 WF=4 N=6 WA=1 SA=0</li>
<li>Allow void? SF=6 WF=9 N=2 WA=0 SA=0</li>
<li>Provide multi-visitation <code>visit(VISITOR, var1, var2, var3, ...)</code>? SF=0 WF=7 N=7 WA=1 SA=0</li>
<li>Provide binary visitation <code>visit(VISITOR, v1, v2)</code>? SF=0 WF=1 N=10 WA=1 SA=3</li>
<li>Approval vote of visitor return types:</li>
<li><code>common_type</code>: 12</li>
<li>require same return type: 13</li>
<li>return type of <code>op()()</code>, rest must convert to that: 1</li>
<li><code>variant&lt;return types&gt;</code>: 2</li>
<li><code>variant&lt;return types&gt;</code> if they're different, otherwise single return type: 0</li>
<li>no <code>void * data()</code></li>
<li>yes <code>T* get&lt;T&gt;(variant&lt;A, B, C&gt; *)</code> (a la <code>any_cast</code>)</li>
<li>Should <code>index()</code> return -1 on empty? (The alternative is to make non-emptiness a precondition.) SF=4 WF=1 N=3 WA=1 SA=2</li>
<li>Should <code>variant::{visit,get}</code> have preconditions that the <code>variant</code> not be empty? SF=4 WF=8 N=2 WA=0 SA=0</li>
</ul>
<h3 id="results-of-the-second-lewg-review-in-lenexa">Results of the second LEWG review in Lenexa</h3>
<ul>
<li>Name of empty state:</li>
<li>empty: 0</li>
<li>error: 6</li>
<li>invalid: 14</li>
<li>bad: 5</li>
<li>fail: 0</li>
<li>partially formed: 4</li>
<li>Name of query function:
<ul>
<li>query function: valid 13</li>
<li>is_valid 2</li>
<li>invalid 1</li>
<li>is_invalid 2</li>
<li>explicit operator bool 7</li>
<li>index() == tuple_not_found 10</li>
</ul></li>
<li>Upon invalid, should index return a magic value? SF=5, F=3, N=1, A=2, SA=2</li>
<li>index() has a precondition of being valid() (otherwise UB) SF=5 F=2 N=0 A=3 SA=3</li>
<li>What do we want to call the "empty_t" stand-in type?
<ul>
<li>empty_t 4</li>
<li>empty 4</li>
<li>one_t 1</li>
<li>blank 6</li>
<li>blank_t 7</li>
<li>monostate 7</li>
</ul>
Runoff:
<ul>
<li>blank* 3</li>
<li>monostate 8</li>
</ul></li>
<li>Add assignment from an exact type if the type is unique? Unanimous consent.</li>
<li>Add an example of multi-visitation; change visit() to a variadic signature.</li>
<li>Keep names in_place_type and in_place_index to be consistent with optional? General consent.</li>
</ul>

<h3 id="results-of-evening-session-review-in-kona">Results of Evening Session review in Kona</h3>
<ul>
<li>Do we want P0088R0 + exceptions on invalid (so no undefined behavior)? SF=13, F=15, N=2, A=3, SA=0</li>
</ul>

<h3 id="results-of-lewg-session-in-kona">Results of LEWG Session in Kona</h3>
<p>This addressed items raised by LWG.</p>

<ul><li>LEWG accepted (and embraced!) LWG's proposal for the overload resolution mechanism for <code>template &lt;class T&gt; variant operator=(T&amp;&amp;)</code>, using a hypothetical function taking the alternative types.</li>
    <li>Allow conversion in both construction and assignment. The detailed polls were:
        <ul>
            <li>keep assignment and construction asymmetrical: SF=0, F=0, N=1, A=7, SA=6</li>
            <li>restrict assign and construction to alternative types only: SF=2, F=5, N=4, A=3, SA=4</li>
            <li>allow conversion for construction and assignment: SF=4, F=4, N=3, A=4, SA=0</li>
        </ul>
    </li>
    <li>Allow visitation without passing a variant, i.e. <code>visit(Visitor)</code>.</li>
    <li>Strong consensus to rename <code>valid()</code> to <code>!corrupted_by_exception()</code> (14 votes, runner-up: 7 votes) that was later on changed to <code>!valueless_by_exception()</code> after a discussion and based on a poll on the LWG and LEWG email lists, with 32 responses.</li>
</ul>

<h3 id="differences-to-revision-1-n4218">Differences to revision 1 (N4218)</h3>
<p>As requested by the LEWG review in Urbana, this revision</p>
<ul>
<li>considerably expands the discussion of why this proposal allows the <code>variant</code> to be empty;</li>
<li>explains how duplicate (possibly <em>cv</em>-qualified) types and <code>void</code> as alternatives behave;</li>
<li>reuses (and extends, for consistency) the facilities provided by <code>tuple</code> for parameter pack operations; <code>is_alternative</code> does not yet exist as part of <code>tuple</code> and is thus kept;</li>
<li>employs the "perfect initialization" approach to for explicit conversions <span class="citation" data-cites="PERFECTINIT">(2)</span>;</li>
<li>changes <code>index()</code> to return <code>-1</code> (now also known is <code>tuple_not_found</code>) if <code>!valid()</code>;</li>
<li>adds a visitation interface.</li>
</ul>
<p>Beyond these requests, this revision</p>
<ul>
<li>discusses the options for relational operators, construction and assignments, with / from a same-type <code>variant</code>, an alternative, and a different <code>variant</code> type;</li>
<li>hopefully makes the <code>variant</code> a regular type.</li>
</ul>
<h3 id="differences-to-revision-2-n4450">Differences to revision 2 (N4450)</h3>
<ul>
<li>Everything requested by LEWG, most notably, <code>variant</code> now models a discriminated union.</li>
<li><code>hash&lt;variant&lt;int&gt;&gt;</code> can now return different values than <code>hash&lt;int&gt;</code> (and it should - presumably it should take the index() into account).</li>
<li>Describe <code>template &lt;size_t,...&gt; get&lt;I,...&gt;(variant)</code>.</li>
<li>Remove <code>is_alternative</code> that is not strictly needed to make <code>variant</code> usable (LEWG feedback).</li>
<li>Remove <code>std::swap()</code> specialization; the default is just fine.</li>
<li>Add obligatory introductory quote.</li>
<li>Expanded on disadvantages of double buffering.</li>
</ul>
<h3 id="differences-to-revision-3-n4516">Differences to revision 3 (N4516)</h3>
<ul>
<li>Added discussion of (semi-) destructive move.</li>
<li>Assignment from an alternative types are back.</li>
<li>Multi-visitation example added.</li>
<li><code>visit()</code> is now variadic.</li>
<li>Implemented several suggestions by Peter Dimov: removed <code>type_list</code>; reduced probability of <code>!valid()</code> for copy assignment / construction.</li>
<li>Renamed to monostate, get_if().</li>
</ul>
<h3 id="differences-to-revision-4-n4542">Differences to revision 4 (N4542)</h3>
<ul>
<li>Make <code>valid()</code> a visible state for value extraction functions (<code>get()</code>, <code>visit()</code>).</li>
<li>Move general design discussion into P0086.</li>
<li>Remove <code>valid()</code> precondition for copy / move construction from a <code>variant</code>.</li>
</ul>
<h3 id="differences-to-revision-5-p0088r0">Differences to revision 5 (P0088R0)</h3>
<ul>
<li>The Kona compromise: f <code>!v.valid()</code>, make <code>get&lt;...&gt;(v)</code> and <code>visit(v)</code> throw.</li>
<li>Change the overload resolution mechanism for <code>template &lt;class T&gt; variant::variant(T&amp;&amp;)</code> and <code>template &lt;class T&gt; variant::operator=(T&amp;&amp;)</code>, using a hypothetical function taking the alternative types.</li>
<li>Allow conversion in both construction and assignment.</li>
<li>Allow visitation without passing a variant, i.e. <code>visit(Visitor)</code>.</li>
<li>Rename <code>valid()</code> to <code>!valueless_by_exception()</code>, following the strong recommendation from a L(E)WG poll.</li>
<li>Remove <code>tuple_find</code>: it was not relevant for using <code>variant</code> as that already provides index- and type-based accesses; it was a considerable fraction of the proposed wording; it warrants a dedicated design paper, should someone wish to have it.</li>
<li>Provide real wording. Fixes:
  <ul>
    <li><code>emplaced_</code>... becomes <code>in_place_</code>...</li>
    <li>provide intended basic <code>constexpr</code> support: construction, accessors, destruction,</li>
    <li>implement all requests from the LWG review at Kona.</li>
  </ul>
  </li>
</ul>


<h2 id="discussion">Discussion</h2>
<h3 id="additional-empty-state">Additional empty state</h3>
<p>LEWG opted against introducing an explicit additional variant state, representing its invalid (and possibly empty, default constructed) state. This is meant to simplify the <code>variant</code> use: as getting a <code>variant</code> into the invalid state is sufficiently difficult, it was felt that there is no need to regularly check for a variant becoming invalid. This prevents all <code>get&lt;int&gt;(v)</code> calls from being protected by <code>if (v.valid())</code>.</p>
<h3 id="visibility-of-the-invalid-state">Visibility of the Invalid State</h3>
<p>Accessing an invalid variant's value is undefined behavior, whatever alternative is accessed.</p>
<p>The <code>variant</code>'s invalid state needs to be visible: accessing its contents or visiting it will violate preconditions; users must be able to verify that a <code>variant</code> is not in this state.</p>
<p>When in the invalid state, <code>index()</code> returns <code>tuple_not_found</code>; <code>variant</code> provides <code>valid()</code> as a usability feature.</p>
<p>This usually does not need to be checked given how rare the invalid case is. It (generally) keeps a variant with N alternatives as an N-state type.</p>
<h3 id="empty-state-and-default-construction">Empty state and default construction</h3>
<p>Default construction of a <code>variant</code> should be allowed, to increase usability for instance in containers. LEWG opted against a <code>variant</code> default-initialized into its invalid state, to make invalid <code>variant</code>s really rare.</p>
<p>Instead, the <code>variant</code> can be initialized with the first alternative (similar to the behavior of initialization of a <code>union</code>) only if that is default constructible. For cases where this behavior should be explicit, and for cases where no such default constructible alternative exists, there is a separate type <code>monostate</code> that can be used as first alternative, to explicitly enable default construction.</p>
<h3 id="feature-test">Feature Test</h3>
<p>No header called <code>variant</code> exists; testing for this header's existence is thus sufficient.</p>

<h2 id="proposed-wording">Proposed wording</h2>
<p>The insertions and deletions in this section describe the changes to 
    the Fundamentals TS. Grayish background indicates proposed wording.</p>    


<h3 id="variant-objects">Variant Objects</h3>
  
  <p>
  Insert a new element in <em>Table 1, C++ library headers</em> of [general.namespaces], named <code>&lt;experimental/variant&gt;</code>.</p>
Insert a new section:
<blockquote class="std">
<h3>? Variants <span class="section_name">[variant]</span></h3>
<h4>?.1 In general <span class="section_name">[variant.general]</span></h4>
<p>Variant objects hold and manage the lifetime of a value. If the variant holds a value, that value's type has to be one of the template argument types given to <code>variant</code>. These template arguments are called alternatives.</p>
  
<h4>?.2 Header <code>&lt;experimental/variant&gt;</code> synopsis <span class="section_name">[variant.synopsis]</span></h4>
<pre>
<code>
namespace std {
namespace experimental {
inline namespace fundamentals_vXXXX {
  <em>// ?.3,</em> variant <em>of value types</em>
  template &lt;class... Types&gt; class variant;

  <em>// ?.4, In-place construction</em>
  template &lt;class T&gt; struct in_place_type_t{};
  template &lt;class T&gt; constexpr in_place_type_t&lt;T&gt; in_place_type{};

  template &lt;size_t I&gt; struct in_place_index_t{};
  template &lt;size_t I&gt; constexpr in_place_index_t&lt;I&gt; in_place_index{};

  <em>// ?.5, Value access</em>
  template &lt;class T, class... Types&gt;
    constexpr bool holds_alternative(const variant&lt;Types...&gt;&amp;) noexcept;

  template &lt;size_t I, class... Types&gt;
    constexpr tuple_element_t&lt;I, variant&lt;Types...&gt;&gt;&amp;
    get(variant&lt;Types...&gt;&amp;);
  template &lt;size_t I, class... Types&gt;
    constexpr tuple_element_t&lt;I, variant&lt;Types...&gt;&gt;&amp;&amp;
    get(variant&lt;Types...&gt;&amp;&amp;);
  template &lt;size_t I, class... Types&gt;
    constexpr tuple_element_t&lt;I, variant&lt;Types...&gt;&gt; const&amp;
    get(const variant&lt;Types...&gt;&amp;);
  template &lt;size_t I, class... Types&gt;
    constexpr tuple_element_t&lt;I, variant&lt;Types...&gt;&gt; const&amp;&amp;
    get(const variant&lt;Types...&gt;&amp;&amp;);

  template &lt;class T, class... Types&gt;
    constexpr T&amp; get(variant&lt;Types...&gt;&amp;);
  template &lt;class T, class... Types&gt;
    constexpr T&amp;&amp; get(variant&lt;Types...&gt;&amp;&amp;);
  template &lt;class T, class... Types&gt;
    constexpr const T&amp; get(const variant&lt;Types...&gt;&amp;);
  template &lt;class T, class... Types&gt;
    constexpr const T&amp;&amp; get(const variant&lt;Types...&gt;&amp;&amp;);

  template &lt;size_t I, class... Types&gt;
    constexpr add_pointer_t&lt;tuple_element_t&lt;I, variant&lt;Types...&gt;&gt;&gt;
    get_if(variant&lt;Types...&gt;*) noexcept;
  template &lt;size_t I, class... Types&gt;
    constexpr add_pointer_t&lt;const tuple_element_t&lt;I, variant&lt;Types...&gt;&gt;&gt;
    get_if(const variant&lt;Types...&gt;*) noexcept;

  template &lt;class T, class... Types&gt;
    constexpr add_pointer_t&lt;T&gt; get_if(variant&lt;Types...&gt;*) noexcept;
  template &lt;class T, class... Types&gt;
    constexpr add_pointer_t&lt;const T&gt; get_if(const variant&lt;Types...&gt;*) noexcept;

  <em>// ?.6, Relational operators</em>
  template &lt;class... Types&gt;
    constexpr bool operator==(const variant&lt;Types...&gt;&amp;,
                              const variant&lt;Types...&gt;&amp;);
  template &lt;class... Types&gt;
    constexpr bool operator!=(const variant&lt;Types...&gt;&amp;,
                              const variant&lt;Types...&gt;&amp;);
  template &lt;class... Types&gt;
    constexpr bool operator&lt;(const variant&lt;Types...&gt;&amp;,
                                const variant&lt;Types...&gt;&amp;);
  template &lt;class... Types&gt;
    constexpr bool operator&gt;(const variant&lt;Types...&gt;&amp;,
                                const variant&lt;Types...&gt;&amp;);
  template &lt;class... Types&gt;
    constexpr bool operator&lt;=(const variant&lt;Types...&gt;&amp;,
                                const variant&lt;Types...&gt;&amp;);
  template &lt;class... Types&gt;
    constexpr bool operator&gt;=(const variant&lt;Types...&gt;&amp;,
                                 const variant&lt;Types...&gt;&amp;);

  <em>// ?.7, Visitation</em>
  template &lt;class Visitor, class... Variants&gt;
  constexpr <em>see below</em> visit(Visitor&amp;&amp;, Variants&amp;&amp;...);

  <em>// ?.8, Class</em> monostate
  struct monostate;

  <em>// ?.9,</em> monostate <em>relational operators</em>
  constexpr bool operator&lt;(monostate, monostate) noexcept;
  constexpr bool operator&gt;(monostate, monostate) noexcept;
  constexpr bool operator&lt;=(monostate, monostate) noexcept;
  constexpr bool operator&gt;=(monostate, monostate) noexcept;
  constexpr bool operator==(monostate, monostate) noexcept;
  constexpr bool operator!=(monostate, monostate) noexcept;

  <em>// ?.10, Specialized algorithms</em>
  template &lt;class... Types&gt;
  void swap(variant&lt;Types...&gt;&amp;, variant&lt;Types...&gt;&amp;) noexcept(<em>see below</em>);

  <em>// ?.11,</em> class bad_variant_access
  class bad_variant_access;
  
} // namespace fundamentals_vXXXX
} // namespace experimental

  <em>// ?.12,</em> tuple <em>interface</em>
  template &lt;class... Types&gt;
    struct tuple_size&lt;variant&lt;Types...&gt;&gt;;
  template &lt;size_t I, class... Types&gt;
    struct tuple_element&lt;I, variant&lt;Types...&gt;&gt;;

  <em>// ?.13, Hash support</em>
  template &lt;class T&gt; struct hash;
  template &lt;class... Types&gt; struct hash&lt;experimental::variant&lt;Types...&gt;&gt;;
  template &lt;&gt; struct hash&lt;experimental::monostate&gt;;

  <em>// ?.14, Allocator-related traits</em>
  template &lt;class R, class Alloc&gt;
  struct uses_allocator&lt;experimental::variant&lt;R&gt;, Alloc&gt;;
} // namespace std
</code>
</pre>

<p>Including this header also makes the following templates from [tuple.helper] available:</p>
<pre><code>
template &lt;class T&gt; class tuple_size&lt;const T&gt;;
template &lt;class T&gt; class tuple_size&lt;volatile T&gt;;
template &lt;class T&gt; class tuple_size&lt;const volatile T&gt;;

template &lt;size_t I, class T&gt; class tuple_element&lt;I, const T&gt;;
template &lt;size_t I, class T&gt; class tuple_element&lt;I, volatile T&gt;;
template &lt;size_t I, class T&gt; class tuple_element&lt;I, const volatile T&gt;;
</code></pre>

  
<h4>?.3 <code>variant</code> of value types <span class="section_name">[variant.variant]</span></h4>
<pre>
<code>
namespace std {
namespace experimental {
inline namespace fundamentals_vXXXX {
  template &lt;class... Types&gt;
  class variant {
  public:

    <em>// ?.3.1 Constructors</em>
    constexpr variant() noexcept(<em>see below</em>);
    variant(const variant&amp;) noexcept(<em>see below</em>);
    variant(variant&amp;&amp;) noexcept(<em>see below</em>);

    template &lt;class T&gt; constexpr variant(T&amp;&amp;);

    template &lt;class T, class... Args&gt;
      constexpr explicit variant(in_place_type_t&lt;T&gt;, Args&amp;&amp;...);
    template &lt;class T, class U, class... Args&gt;
      constexpr explicit variant(in_place_type_t&lt;T&gt;, initializer_list&lt;U&gt;, Args&amp;&amp;...);

    template &lt;size_t I, class... Args&gt;
      constexpr explicit variant(in_place_index_t&lt;I&gt;, Args&amp;&amp;...);
    template &lt;size_t I, class U, class... Args&gt;
      constexpr explicit variant(in_place_index_t&lt;I&gt;, initializer_list&lt;U&gt;, Args&amp;&amp;...);

    <em>// allocator-extended constructors</em>
    template &lt;class Alloc&gt;
      variant(allocator_arg_t, const Alloc&amp;);
    template &lt;class Alloc&gt;
      variant(allocator_arg_t, const Alloc&amp; a, const variant&amp;);
    template &lt;class Alloc&gt;
      variant(allocator_arg_t, const Alloc&amp; a, variant&amp;&amp;);
    template &lt;class Alloc, class T&gt;
      variant(allocator_arg_t, const Alloc&amp;, T&amp;&amp;);
    template &lt;class Alloc, class T, class... Args&gt;
      variant(allocator_arg_t, const Alloc&amp;, in_place_type_t&lt;T&gt;, Args&amp;&amp;...);
    template &lt;class Alloc, class T, class U, class... Args&gt;
      variant(allocator_arg_t, const Alloc&amp;, in_place_type_t&lt;T&gt;, initializer_list&lt;U&gt;, Args&amp;&amp;...);
    template &lt;class Alloc, size_t I, class... Args&gt;
      variant(allocator_arg_t, const Alloc&amp;, in_place_index_t&lt;I&gt;, Args&amp;&amp;...);
    template &lt;class Alloc, size_t I, class U, class... Args&gt;
      variant(allocator_arg_t, const Alloc&amp;, in_place_index_t&lt;I&gt;, initializer_list&lt;U&gt;, Args&amp;&amp;...);

    <em>// ?.3.2, Destructor</em>
    ~variant();

    <em>// ?.3.3, Assignment</em>
    variant&amp; operator=(const variant&amp;);
    variant&amp; operator=(variant&amp;&amp;) noexcept(<em>see below</em>);
<!-- REMOVED AS PER LWG @ KONA
    template &lt;class T&gt; variant&amp; operator=(const T&amp;);  -->
    template &lt;class T&gt; variant&amp; operator=(T&amp;&amp;) noexcept(<em>see below</em>);

    <em>// ?.3.4, Modifiers</em>
    template &lt;class T, class... Args&gt; void emplace(Args&amp;&amp;...);
    template &lt;class T, class U, class... Args&gt;
      void emplace(initializer_list&lt;U&gt;, Args&amp;&amp;...);
    template &lt;size_t I, class... Args&gt; void emplace(Args&amp;&amp;...);
    template &lt;size_t I, class U, class... Args&gt;
      void emplace(initializer_list&lt;U&gt;, Args&amp;&amp;...);

    <em>// ?.3.5, Value status</em>
    constexpr bool valueless_by_exception() const noexcept;
    constexpr size_t index() const noexcept;

    <em>// ?.3.6, Swap</em>
    void swap(variant&amp;) noexcept(<em>see below</em>);

  private:
    aligned_storage&lt;Unspecified&gt;::type storage; // <em>exposition only</em>
    size_t value_type_index; // exposition only
  };
} // namespace fundamentals_vXXXX
} // namespace experimental
} // namespace std
</code>
</pre>

<p>Any instance of <code>variant</code> at any given time either holds a value of one of its alternative types, or it holds no value. When an instance of <code>variant</code> holds a value of alternative type <code>T</code>, it means that a value of type <code>T</code>, referred to as the <code>variant</code> object's contained value, is allocated within the storage of the <code>variant</code> object. Implementations are not permitted to use additional storage, such as dynamic memory, to allocate the contained value. The contained value shall be allocated in a region of the <code>variant</code> storage suitably aligned for all types in <code>Types</code>. It is implementation defined whether over-aligned types are supported.</p>

<p>All types in <code>Types</code> shall be object types, possibly <em>cv</em>-qualified, possibly <em>cv</em>-qualified void, or references. [<em>Note:</em> Implementations could decide to store references in a <code>reference_wrapper</code>. <em>&mdash; end note</em>]</p>

<h4>?.3.1 Constructors <span class="section_name">[variant.ctor]</span></h4>
<p>In the descriptions that follow, let <code>i</code> be in the range <code>[0,sizeof...(Types))</code>, and <code>T_i</code> be the <code>i</code><sup>th</sup> type in <code>Types...</code>.</p>

<p class="function">
<code>
constexpr variant() noexcept(<em>see below</em>);
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>Constructs a <code>variant</code> holding a value-initialized value of type <code>T_0</code>.
</dd>
<dt>Postconditions:</dt>
<dd><code>valueless_by_exception()</code> is <code>false</code> and <code>index()</code> is <code>0</code>.
</dd>
<dt>Throws:</dt>
<dd>Any exception thrown by the value initialization of <code>T_0</code>.
</dd>
<dt>Remarks:</dt>
<dd>This function shall be <code>noexcept</code> if and only if the value initialization of the alternative type <code>T_0</code> would satisfy the requirements for a <code>constexpr</code> function. The expression inside <code>noexcept</code> is equivalent to <code>is_nothrow_default_constructible_v&lt;T_0&gt;</code>. This function shall not participate in overload resolution unless <code>is_default_constructible_v&lt;T_0&gt;</code> is <code>true</code>. [<em>Note:</em> see also class <code>monostate</code>. <em>&mdash; end note</em>]</dd>
</dl>
  
<p class="function">
<code>
variant(const variant&amp; w);
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>If <code>w</code> holds a value, initializes the <code>variant</code> to hold the same alternative as <code>w</code> and direct-initializes the contained value from the value contained in <code>w</code>. Otherwise, initializes the <code>variant</code> to not hold a value.</dd>
<dt>Throws:</dt>
<dd>Any exception thrown by direct-initializing any <code>T_i</code> for all <code>i</code>.
</dd>
<dt>Remarks:</dt>
  <dd>This function shall not participate in overload resolution unless <code>is_copy_constructible_v&lt;T_i&gt;</code> is <code>true</code> for all <code>i</code>.</dd></dl>
  
<p class="function">
<code>
variant(variant&amp;&amp; w) noexcept(<em>see below</em>);
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>If <code>w</code> holds a value, initializes the <code>variant</code> to hold the same alternative as <code>w</code> and direct-initializes the contained value with <code>std::forward&lt;T_j&gt;(get&lt;j&gt;(w))</code>, where <code>j</code> is <code>w.index()</code>. Otherwise, initializes the <code>variant</code> to not hold a value.</dd>
<dt>Throws:</dt>
  <dd>Any exception thrown by move-constructing any <code>T_i</code> for all <code>i</code>.</dd>
<dt>Remarks:</dt>
<dd>The expression inside <code>noexcept</code> is equivalent to the logical AND of <code>is_nothrow_move_constructible_v&lt;T_i&gt;</code> for all <code>i</code>.
This function shall not participate in overload resolution unless <code>is_move_constructible_v&lt;T_i&gt;</code> is <code>true</code> for all <code>i</code>.
</dd>
</dl>

<p class="function">
<code>
template &lt;class T&gt; constexpr variant(T&amp;&amp; t);
</code>
</p>
<dl class="attribute">
  <dt>Requires:</dt>
  <dd>Builds an imaginary function <code><em>FUN</em>(T_i)</code> for each alternative type <code>T_i</code>. The expression <code><em>FUN</em>(std::forward&lt;T&gt;(t))</code> must be valid according to regular overload resolution, otherwise the program is ill-formed. The selected function <code><em>FUN</em>(T_j)</code> defines the alternative <code>T_j</code> that will be activated by the call to this constructor. [<em>Note:</em>
<pre>
<code>
variant&lt;string, string&gt; v("abc");
</code>
</pre>
is ill-formed, as both alternative types have an equally viable constructor for the argument. <em>&mdash; end note</em>]
</dd>

<dt>Effects:</dt>
  <dd>Initializes <code>*this</code> to hold the alternative type <code>T_j</code> as selected by the imaginary function overload resolution described above, and direct-initializes the contained value as if direct-non-list-initializing it with <code>std::forward&lt;T&gt;(t)</code>.
</dd>
<dt>Postconditions:</dt>
<dd><code>holds_alternative&lt;T_j&gt;(*this)</code> is <code>true</code>, with <code>T_j</code> selected by the imaginary function overload resolution described above.
</dd>
<dt>Throws:</dt>
<dd>Any exception thrown by the initialization of the selected alternative <code>T_j</code>.
</dd>
<dt>Remarks:</dt>
<dd>This function shall not participate in overload resolution unless <code>is_same_v&lt;decay_t&lt;T&gt;, variant&gt;</code> is <code>false</code>. If <code>T_j</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor shall be a <code>constexpr</code> constructor.
</dd>
</dl>
  
<p class="function">
<code>
template &lt;class T, class... Args&gt; constexpr explicit variant(in_place_type_t&lt;T&gt;, Args&amp;&amp;... args);
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>Initializes the contained value as if constructing an object of type <code>T</code> with the arguments <code>std::forward&lt;Args&gt;(args)...</code>.
</dd>
<dt>Postcondition:</dt>
<dd><code>holds_alternative&lt;T&gt;(*this)</code> is <code>true</code>.
</dd>
<dt>Throws:</dt>
<dd>Any exception thrown by calling the selected constructor of <code>T</code>.
</dd>
<dt>Remarks:</dt>
<dd>This function shall not participate in overload resolution unless there is exactly one occurrences of <code>T</code> in <code>Types...</code> and <code>is_constructible_v&lt;T, Args&amp;&amp;...&gt;</code> is <code>true</code>. If <code>T</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor shall be a <code>constexpr</code> constructor.
</dd>
</dl>

<p class="function">
<code>
template &lt;class T, class U, class... Args&gt; constexpr explicit variant(in_place_type_t&lt;T&gt;, initializer_list&lt;U&gt; il, Args&amp;&amp;... args);
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>Initializes the contained value as if constructing an object of type <code>T</code> with the arguments <code>il, std::forward&lt;Args&gt;(args)...</code>.
</dd>
<dt>Postcondition:</dt>
<dd><code>holds_alternative&lt;T&gt;(*this)</code> is <code>true</code>.
</dd>
<dt>Throws:</dt>
<dd>Any exception thrown by calling the selected constructor of <code>T</code>.
</dd>
<dt>Remarks:</dt>
<dd>This function shall not participate in overload resolution unless there is exactly one occurrences of <code>T</code> in <code>Types...</code> and <code>is_constructible_v&lt;T, initializer_list&lt;U&gt;&amp;, Args&amp;&amp;...&gt;</code> is <code>true</code>. If <code>T</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor shall be a <code>constexpr</code> constructor.
</dd>
</dl>

<p class="function">
<code>
template &lt;size_t I, class... Args&gt; constexpr explicit variant(in_place_index_t&lt;I&gt;, Args&amp;&amp;... args);
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>Initializes the contained value as if constructing an object of type <code>T_I</code> with the arguments <code>std::forward&lt;Args&gt;(args)...</code>.
</dd>
<dt>Postcondition:</dt>
<dd><code>index()</code> is <code>I</code>.
</dd>
<dt>Throws:</dt>
<dd>Any exception thrown by calling the selected constructor of <code>T_I</code>.
</dd>
<dt>Remarks:</dt>
<dd>This function shall not participate in overload resolution unless <code>I</code> is less than <code>sizeof...(Types)</code> and <code>is_constructible_v&lt;T_I, Args&amp;&amp;...&gt;</code> is <code>true</code>. If <code>T_I</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor shall be a <code>constexpr</code> constructor.
</dd>
</dl>

<p class="function">
<code>
template &lt;size_t I, class U, class... Args&gt; constexpr explicit variant(in_place_index_t&lt;I&gt;, initializer_list&lt;U&gt; il, Args&amp;&amp;... args);
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>Initializes the contained value as if constructing an object of type <code>T_I</code> with the arguments <code>il, std::forward&lt;Args&gt;(args)...</code>.
</dd>
<dt>Postcondition:</dt>
<dd><code>index()</code> is <code>I</code>.
</dd>
<dt>Remarks:</dt>
<dd>This function shall not participate in overload resolution unless <code>I</code> is less than <code>sizeof...(Types)</code> and <code>is_constructible_v&lt;T_I, initializer_list&lt;U&gt;&amp;, Args&amp;&amp;...&gt;</code> is <code>true</code>. If <code>T_I</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor shall be a <code>constexpr</code> constructor.
</dd>
</dl>

<p class="function">
<code>
// allocator-extended constructors<br/>
template &lt;class Alloc&gt;<br/>
&nbsp; variant(allocator_arg_t, const Alloc&amp; a);<br/>
template &lt;class Alloc&gt;<br/>
&nbsp; variant(allocator_arg_t, const Alloc&amp; a, const variant&amp; v);<br/>
template &lt;class Alloc&gt;<br/>
&nbsp; variant(allocator_arg_t, const Alloc&amp; a, variant&amp;&amp; v);<br/>
template &lt;class Alloc, class T&gt;<br/>
&nbsp; variant(allocator_arg_t, const Alloc&amp; a, T&amp;&amp; t);<br/>
template &lt;class Alloc, class T, class... Args&gt;<br/>
&nbsp; variant(allocator_arg_t, const Alloc&amp; a,
in_place_type_t&lt;T&gt;, Args&amp;&amp;... args);<br/>
template &lt;class Alloc, class T, class U, class... Args&gt;<br/>
&nbsp; variant(allocator_arg_t, const Alloc&amp; a,
in_place_type_t&lt;T&gt;, initializer_list&lt;U&gt; il, Args&amp;&amp;... args);<br/>
template &lt;class Alloc, size_t I, class... Args&gt;<br/>
&nbsp; variant(allocator_arg_t, const Alloc&amp; a,
in_place_index_t&lt;I&gt;, Args&amp;&amp;... args);<br/>
template &lt;class Alloc, size_t I, class U, class... Args&gt;<br/>
&nbsp; variant(allocator_arg_t, const Alloc&amp; a,
in_place_index_t&lt;I&gt;, initializer_list&lt;U&gt; il, Args&amp;&amp;... args);<br/>
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
  <dd><code>Alloc</code> shall meet the requirements for an <code>Allocator</code> (17.6.3.5).</dd>
<dt>Effects:</dt>
  <dd>Equivalent to the preceding constructors except that the contained value is constructed with uses-allocator construction (20.7.7.2).</dd>
</dl>
  
<h4 id="destructor">?.3.2 Destructor <span class="section_name">[variant.dtor]</span></h4>
<p class="function">
<code>
~variant();
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>If <code>valueless_by_exception()</code> is <code>false</code>, destroys the currently contained value.
</dd>
  <dt>Remarks:</dt>
  <dd>If <code>is_trivially_destructible_v&lt;T_i&gt; == true</code> for all <code>T_i</code> then this destructor shall be a trivial destructor.</dd>
</dl>

<h4 id="assignment">?.3.3 Assignment <span class="section_name">[variant.assign]</span></h4>
  <p class="function">
<code>
variant&amp; operator=(const variant&amp; rhs);
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd><br/><ul>
  <li>If neither <code>*this</code> nor <code>rhs</code> hold a value, no effect. Otherwise</li>
  <li>if <code>*this</code> holds a value but <code>rhs</code> does not, destroys the value contained in <code>*this</code> and sets <code>*this</code> to not hold a value. Otherwise,</li>
  <li>if <code>index() == rhs.index()</code>, assigns the value contained in <code>rhs</code> to the value contained in <code>*this</code>. Otherwise,</li>
  <li>copies the value contained in <code>rhs</code> to a temporary, then destroys any value contained in <code>*this</code>. Sets <code>*this</code> to hold the same alternative index as <code>rhs</code> and initializes the value contained in <code>*this</code> as if direct-non-list-initializing an object of type <code>T_j</code> with <code>std::forward&lt;T_j&gt;(TMP)</code>, with <code>TMP</code> being the temporary and <code>j</code> being <code>rhs.index()</code>.</li>
</ul>
<br/>
    <ul>
  <li>If an exception is thrown during the call to <code>T_j</code>'s copy assignment, the state of the contained value is as defined by the exception safety guarantee of <code>T_j</code>'s copy assignment; <code>index()</code> will be <code>j</code>.</li>
  <li>If an exception is thrown during the call to <code>T_j</code>'s copy constructor (with <code>j</code> being <code>rhs.index()</code>), <code>*this</code> will remain unchanged.</li>
    <li>If an exception is thrown during the call to <code>T_j</code>'s move constructor, the <code>variant</code> will hold no value.</li>
  </ul>
  </dd>
<dt>Returns:</dt>
<dd><code>*this</code>.
</dd>
<dt>Postconditions:</dt>
<dd><code>index() == rhs.index()</code>
</dd>
  <dt>Remarks:</dt>
  <dd>This function shall not participate in overload resolution unless <code>is_copy_constructible_v&lt;T_i&gt; &amp;&amp; is_move_constructible_v&lt;T_i&gt; &amp;&amp; is_copy_assignable_v&lt;T_i&gt;</code> is <code>true</code> for all <code>i</code>.</dd>
</dl>

<p class="function">
<code>
variant&amp; operator=(variant&amp;&amp; rhs) noexcept(<em>see below</em>);
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd><br/><ul>
  <li>If neither <code>*this</code> nor <code>rhs</code> hold a value, no effect. Otherwise</li>
  <li>if <code>*this</code> holds a value but <code>rhs</code> does not, destroys the value contained in <code>*this</code> and sets <code>*this</code> to not hold a value. Otherwise,</li>
  <li>if <code>index() == rhs.index()</code>, assigns <code>std::forward&lt;T_j&gt;(get&lt;j&gt;(rhs))</code> to the value contained in <code>*this</code>, with <code>j</code> being <code>index()</code>. Otherwise,</li>
  <li>destroys any value contained in <code>*this</code>. Sets <code>*this</code> to hold the same alternative index as <code>rhs</code> and initializes the value contained in <code>*this</code> as if direct-non-list-initializing an object of type <code>T_j</code> with <code>std::forward&lt;T_j&gt;(get&lt;j&gt;(rhs))</code> with <code>j</code> being <code>rhs.index()</code>.</li>
</ul>
  <br/>
  If an exception is thrown during the call to <code>T_j</code>'s move constructor (with <code>j</code> being <code>rhs.index()</code>), the <code>variant</code> will hold no value. If an exception is thrown during the call to <code>T_j</code>'s move assignment, the state of the contained value is as defined by the exception safety guarantee of <code>T_j</code>'s move assignment; <code>index()</code> will be <code>j</code>.

</dd>
<dt>Returns:</dt>
<dd><code>*this</code>.
</dd>
<dt>Remarks:</dt>
<dd>This function shall not participate in overload resolution unless <code>is_move_constructible_v&lt;T_i&gt; &amp;&amp; is_move_assignable_v&lt;T_i&gt;</code> is <code>true</code> for all <code>i</code>. The expression inside <code>noexcept</code> is equivalent to: <code>is_nothrow_move_constructible_v&lt;T_i&gt; &amp;&amp; is_nothrow_move_assignable_v&lt;T_i&gt;</code> for all <code>i</code>.
</dd>
</dl>
  
<p class="function">
<code>
  <!-- REMOVED AS PER LWG @ KONA
template &lt;class T&gt; variant&amp; operator=(const T&amp; t);-->
template &lt;class T&gt; variant&amp; operator=(T&amp;&amp; t) noexcept(<em>see below</em>);
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
  <dd>Builds an imaginary function <code><em>FUN</em>(T_i)</code> for each alternative type <code>T_i</code>. The expression <code><em>FUN</em>(std::forward&lt;T&gt;(t))</code> must be valid according to regular overload resolution, otherwise the program is ill-formed. The selected function <code><em>FUN</em>(T_j)</code> defines the alternative <code>T_j</code> that will be activated by the assignment. [<em>Note:</em>
<pre>
<code>
variant&lt;string, string&gt; v;
v = &quot;abc&quot;;
</code>
</pre>
is ill-formed, as both alternative types have an equally viable constructor for the argument. <em>&mdash; end note</em>]
</dd>
<dt>Effects:</dt>
  <dd>No effect if <code>decay_t&lt;T&gt;(t)</code> is <code>void</code>. If <code>*this</code> holds a <code>T_j</code>, assigns <code>std::forward&lt;T&gt;(t)</code> to the value contained in <code>*this</code>.
  Otherwise, destroys any value contained in <code>*this</code>, sets <code>*this</code> to hold the alternative type <code>T_j</code> as selected by the imaginary function overload resolution described above, and direct-initializes the contained value as if direct-non-list-initializing it with <code>std::forward&lt;T&gt;(t)</code>.
<br/>
If an exception is thrown during the assignment of <code>std::forward&lt;T&gt;(t)</code> to the value contained in <code>*this</code>, the state of the contained value and <code>t</code> are as defined by the exception safety guarantee of the assignment expression; <code>valueless_by_exception()</code> will be <code>false</code>. If an exception is thrown during the initialization of the contained value, the <code>variant</code> object will not hold a value.
</dd>
<dt>Postcondition:</dt>
<dd><code>holds_alternative&lt;T_j&gt;(*this)</code> is <code>true</code>, with <code>T_j</code> selected by the imaginary function overload resolution described above.
</dd>
<dt>Returns:</dt>
<dd><code>*this</code>.
</dd>
<dt>Remarks:</dt>
<dd>This function shall not participate in overload resolution unless <code>is_same_v&lt;decay_t&lt;T&gt;, variant&gt;</code> is <code>false</code>. The expression inside <code>noexcept</code> is equivalent to: <code>is_nothrow_assignable_v&lt;T_i, T&amp;&amp;&gt; &amp;&amp; is_nothrow_constructible_v&lt;T_i, T&amp;&amp;&gt;</code> for all <code>i</code>.
</dd>
</dl>
  
<h4>?.3.4 Modifiers <span class="section_name">[variant.mod]</span></h4>
<p class="function">
<code>
template &lt;class T, class... Args&gt; void emplace(Args&amp;&amp;... args);
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>Destroys the currently contained value if <code>valueless_by_exception()</code> is <code>false</code>. Then direct-initializes the contained value as if constructing a value of type <code>T</code> with the arguments <code>std::forward&lt;Args&gt;(args)...</code>. If an exception is thrown during the initialization of the contained value, the <code>variant</code> will not hold a value.
</dd>
<dt>Postcondition:</dt>
<dd><code>holds_alternative&lt;T&gt;(*this)</code> is <code>true</code>.
</dd>
<dt>Throws:</dt>
<dd>Any exception thrown during the initialization of the contained value.
</dd>
<dt>Remarks:</dt>
<dd>This function shall not participate in overload resolution unless <code>is_constructible_v&lt;T, Args&amp;&amp;...&gt;</code> is <code>true</code>, and <code>T</code> occurs exactly once in <code>Types...</code>.
</dd>
</dl>
  
<p class="function">
<code>
template &lt;class T, class U, class... Args&gt; void emplace(initializer_list&lt;U&gt; il, Args&amp;&amp;... args);
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>Destroys the currently contained value if <code>valueless_by_exception()</code> is <code>false</code>. Then direct-initializes the contained value as if constructing an object of type <code>T</code> with the arguments <code>il, std::forward&lt;Args&gt;(args)...</code>.
  If an exception is thrown during the initialization of the contained value, the <code>variant</code> will not hold a value.
</dd>
<dt>Postcondition:</dt>
<dd><code>holds_alternative&lt;T&gt;(*this)</code> is <code>true</code>.
</dd>
<dt>Throws:</dt>
<dd>Any exception thrown during the initialization of the contained value.
</dd>
<dt>Remarks:</dt>
<dd>This function shall not participate in overload resolution unless <code>is_constructible_v&lt;T, initializer_list&lt;U&gt;&amp;, Args&amp;&amp;...&gt;</code> is <code>true</code>, and <code>T</code> occurs exactly once in <code>Types...</code>.
</dd>
</dl>

<p class="function">
<code>
template &lt;size_t I, class... Args&gt; void emplace(Args&amp;&amp;... args);
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
  <dd><code>I &lt; sizeof...(Types)</code></dd>
  <dt>Effects:</dt>
<dd>Destroys the currently contained value if <code>valueless_by_exception()</code> is <code>false</code>. Then direct-initializes the contained value as if constructing a value of type <code>T_I</code> with the arguments <code>std::forward&lt;Args&gt;(args)...</code>.
  If an exception is thrown during the initialization of the contained value, the <code>variant</code> will not hold a value.
</dd>
<dt>Postcondition:</dt>
<dd><code>index()</code> is <code>I</code>.
</dd>
<dt>Throws:</dt>
<dd>Any exception thrown during the initialization of the contained value.
</dd>
<dt>Remarks:</dt>
<dd>This function shall not participate in overload resolution unless <code>is_constructible_v&lt;T_I, Args&amp;&amp;...&gt;</code> is <code>true</code>.
</dd>
</dl>

<p class="function">
<code>
template &lt;size_t I, class U, class... Args&gt; void emplace(initializer_list&lt;U&gt; il, Args&amp;&amp;... args);
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
  <dd><code>I &lt; sizeof...(Types)</code></dd>
<dt>Effects:</dt>
<dd>Destroys the currently contained value if <code>valueless_by_exception()</code> is <code>false</code>. Then direct-initializes the contained value as if constructing an object of type <code>T_I</code> with the arguments <code>il, std::forward&lt;Args&gt;(args)...</code>.
  If an exception is thrown during the initialization of the contained value, the <code>variant</code> will not hold a value.
</dd>
<dt>Postcondition:</dt>
<dd><code>index()</code> is <code>I</code>.
</dd>
<dt>Throws:</dt>
<dd>Any exception thrown during the initialization of the contained value.
</dd>
<dt>Remarks:</dt>
<dd>This function shall not participate in overload resolution unless <code>is_constructible_v&lt;T_I, initializer_list&lt;U&gt;&amp;, Args&amp;&amp;...&gt;</code> is <code>true</code>.
</dd>
</dl>


<h4>?.3.5 Value status <span class="section_name">[variant.status]</span></h4>

<p class="function">
<code>
constexpr bool valueless_by_exception() const noexcept;
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>Returns whether the <code>variant</code> holds a value (returns <code>false</code>). [<em>Note:</em>
A <code>variant</code> will not hold a value if an exception is thrown during a type-changing assignment or emplacement. The latter means that even a <code>variant&lt;float,int&gt;</code> can become <code>valueless_by_exception()</code>, for instance by
<pre>
<code>
struct S { operator int() { throw 42; }};
variant&lt;float, int&gt; v{12.f};
v.emplace&lt;1&gt;(S());
</code></pre>
<em>&mdash; end note</em>]
</dd>
</dl>

<p class="function">
<code>
constexpr size_t index() const noexcept;
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>If <code>valueless_by_exception()</code> is <code>true</code>, returns <code>tuple_not_found</code>. Otherwise, returns the index of the currently active alternative.
</dd>
</dl>

<h4>?.3.6 Swap <span class="section_name">[variant.swap]</span></h4>
<p class="function">
<code>
void swap(variant&amp; rhs) noexcept(<em>see below</em>);
</code></p>
<dl class="attribute">
<dt>Effects:</dt>
<dd><br/><ul>
  <li>if <code>valueless_by_exception() &amp;&amp; rhs.valueless_by_exception()</code> no effect, otherwise</li>
  <li>if <code>index() == rhs.index()</code>, calls <code>swap(get&lt;i&gt;(*this), get&lt;i&gt;(rhs))</code> with <code>i</code> being <code>index()</code>, otherwise</li>
  <li>exchanges values of <code>rhs</code> and <code>*this</code>.</li>
</ul>
  <br/>
  If an exception is thrown during the call to function <code>swap(get&lt;i&gt;(*this), get&lt;i&gt;(rhs))</code>, the state of the value of <code>this</code> and of <code>rhs</code> is determined by the exception safety guarantee of <code>swap</code> for lvalues of <code>T_i</code> with <code>i</code> being <code>index()</code>. If an exception is thrown during the exchange of the values of <code>*this</code> and <code>rhs</code>, the state of the value of <code>this</code> and of <code>rhs</code> is determined by the exception safety guarantee of <code>variant</code>'s move constructor and assignment operator.
</dd>
<dt>Throws:</dt>
<dd>Any exceptions that is thrown by <code>swap(get&lt;i&gt;(*this), get&lt;i&gt;(rhs))</code> with <code>i</code> being <code>index()</code> or <code>variant</code>'s move constructor and assignment operator.
</dd>
  <dt>Remarks:</dt>
  <dd>This function shall not participate in overload resolution unless all alternative types satisfy the <code>Swappable</code> requirements (17.6.3.2) with the corresponding alternative in <code>rhs</code>.</dd>
</dl>

<h4>?.4 In-place construction <span class="section_name">[variant.emplaced]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; struct in_place_type_t{};<br/>
template &lt;class T&gt; constexpr in_place_type_t&lt;T&gt; in_place_type{};<br/>
template &lt;size_t I&gt; struct in_place_index_t{};<br/>
template &lt;size_t I&gt; constexpr in_place_index_t&lt;I&gt; in_place_index{};<br/>
</code>
<p>Template specializations of <code>in_place_type_t</code> are empty structure types used as unique types to disambiguate constructor and function overloading. They signal (through the template parameter) the alternative to be constructed. Specifically, <code>variant</code> has a constructor with <code>in_place_type_t&lt;T&gt;</code> as the first argument followed by an argument pack; this indicates that <code>T</code> should be constructed in-place (as if by a call to a placement new expression) with the forwarded argument pack as parameters. If a <code>variant</code>'s <code>Types</code> has multiple occurrences of <code>T</code>, <code>in_place_index_t</code> must be used.</p>
<p>Template specializations of <code>in_place_index_t</code> are empty structure types used as unique types to disambiguate constructor and function overloading, and signaling (through the template parameter) the alternative to be constructed. Specifically, <code>variant</code> has a constructor with <code>in_place_index_t&lt;I&gt;</code> as the first argument followed by an argument pack; this indicates that <code>T_I</code> should be constructed in-place (as if by a call to a placement new expression) with the forwarded argument pack as parameters.</p>


<h4 id="value-access">?.5 Value access <span class="section_name">[variant.get]</span></h4>

<p class="function">
<code>
template &lt;class T, class... Types&gt; constexpr bool holds_alternative(const variant&lt;Types...&gt;&amp; v) noexcept;
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
<dd>The type <code>T</code> occurs exactly once in <code>Types...</code>. Otherwise, the program is ill-formed.
</dd>
<dt>Returns:</dt>
<dd>the zero-based index of <code>T</code> in <code>Types...</code>.
</dd>
</dl>

<!--
  template &lt;size_t I, class... Types&gt;
    tuple_element_t&lt;I, variant&lt;Types...&gt;&gt;&amp;
    get(variant&lt;Types...&gt;&amp;);
  template &lt;size_t I, class... Types&gt;
    tuple_element_t&lt;I, variant&lt;Types...&gt;&gt;&amp;&amp;
    get(variant&lt;Types...&gt;&amp;&amp;);
  template &lt;size_t I, class... Types&gt;
    tuple_element_t&lt;I, variant&lt;Types...&gt;&gt; const&amp;
    get(const variant&lt;Types...&gt;&amp;);
  template &lt;size_t I, class... Types&gt;
    tuple_element_t&lt;I, variant&lt;Types...&gt;&gt; const&amp;&amp;
    get(const variant&lt;Types...&gt;&amp;&amp;);

  template &lt;class T, class... Types&gt;
    T&amp; get(variant&lt;Types...&gt;&amp;);
  template &lt;class T, class... Types&gt;
    const T&amp; get(const variant&lt;Types...&gt;&amp;);
  template &lt;class T, class... Types&gt;
    T&amp;&amp; get(variant&lt;Types...&gt;&amp;&amp;);
  template &lt;class T, class... Types&gt;
    const T&amp;&amp; get(const variant&lt;Types...&gt;&amp;&amp;);
-->

<p class="function">
  <code>
template &lt;size_t I, class... Types&gt;<br/>
&nbsp; constexpr tuple_element_t&lt;I, variant&lt;Types...&gt;&gt;&amp; get(variant&lt;Types...&gt;&amp; v);<br/>
template &lt;size_t I, class... Types&gt;<br/>
&nbsp; constexpr tuple_element_t&lt;I, variant&lt;Types...&gt;&gt;&amp;&amp; get(variant&lt;Types...&gt;&amp;&amp; v);<em>// Note A</em><br/>
template &lt;size_t I, class... Types&gt;<br/>
&nbsp; constexpr tuple_element_t&lt;I, variant&lt;Types...&gt;&gt; const&amp; get(const variant&lt;Types...&gt;&amp; v); // Note B<br/>
template &lt;size_t I, class... Types&gt;<br/>
&nbsp; constexpr tuple_element_t&lt;I, variant&lt;Types...&gt;&gt; const&amp;&amp; get(const variant&lt;Types...&gt;&amp;&amp; v); // Notes A and B
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
<dd><code>I &lt; sizeof...(Types)</code>, and <code>T_I</code> is not a possibly <em>cv</em>-qualified <code>void</code>. Otherwise the program is ill-formed.
</dd>
<dt>Effects:</dt>
<dd>If <code>v.index()</code> is <code>I</code>, returns a reference to the object stored in the variant. Otherwise, throws an exception of type <code>bad_variant_access</code>.
</dd>
  <dt>[<em>Note A:</em></dt>
  <dd>if <code>T_I</code> is some reference type <code>X&amp;</code>, the return type is <code>X&amp;</code>, not <code>X&amp;&amp;</code>. However, if the element type is a non-reference type <code>T</code>, the return type is <code>T&amp;&amp;</code>. <em>&mdash; end note</em>]
  </dd>
  <dt>[<em>Note B:</em></dt>
  <dd>
    Constness is shallow. If <code>T_I</code> is some reference type <code>X&amp;</code>, the return type is <code>X&amp;</code>, not
<code>const X&amp;</code>. However, if the element type is non-reference type <code>T</code>, the return type is <code>const T&amp;</code>. This is
consistent with how constness is defined to work for member variables of reference type. <em>&mdash; end note</em>]
  </dd>
</dl>


<p class="function">
<code>
template &lt;class T, class... Types&gt; constexpr T&amp; get(variant&lt;Types...&gt;&amp; v);<br/>
template &lt;class T, class... Types&gt; constexpr T&amp;&amp; get(variant&lt;Types...&gt;&amp;&amp; v);<br/>
template &lt;class T, class... Types&gt; constexpr const T&amp; get(const variant&lt;Types...&gt;&amp; v);<br/>
template &lt;class T, class... Types&gt; constexpr const T&amp;&amp; get(const variant&lt;Types...&gt;&amp;&amp; v);
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
  <dd>The type <code>T</code> occurs exactly once in <code>Types...</code>, and <code>T</code> is not a possibly <em>cv</em>-qualified <code>void</code>. Otherwise, the program is ill-formed.
</dd>
<dt>Effects:</dt>
<dd>If <code>v</code> holds a value of type <code>T</code>, returns a reference to that value. Otherwise, throws an exception of type <code>bad_variant_access</code>.
  </dd>
</dl>



<!--
  template &lt;size_t I, class... Types&gt;
    add_pointer_t&lt;tuple_element_t&lt;I, variant&lt;Types...&gt;&gt;&gt;
    get_if(variant&lt;Types...&gt;*) noexcept;
  template &lt;size_t I, class... Types&gt;
    add_pointer_t&lt;const tuple_element_t&lt;I, variant&lt;Types...&gt;&gt;&gt;
    get_if(const variant&lt;Types...&gt;*) noexcept;

  template &lt;class T, class... Types&gt;
    add_pointer_t&lt;T&gt; get_if(variant&lt;Types...&gt;*) noexcept;
  template &lt;class T, class... Types&gt;
    add_pointer_t&lt;const T&gt; get_if(const variant&lt;Types...&gt;*) noexcept;
-->

<p class="function">
<code>
template &lt;size_t I, class... Types&gt;<br/>
&nbsp; constexpr add_pointer_t&lt;tuple_element_t&lt;I, variant&lt;Types...&gt;&gt;&gt; get_if(variant&lt;Types...&gt;* v) noexcept;<br/>
template &lt;size_t I, class... Types&gt;<br/>
&nbsp; constexpr add_pointer_t&lt;const tuple_element_t&lt;I, variant&lt;Types...&gt;&gt;&gt; get_if(const variant&lt;Types...&gt;* v) noexcept;
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
<dd><code>I &lt; sizeof...(Types)</code> and <code>T_I</code> is not (possibly <em>cv</em>-qualified) <code>void</code>; otherwise the program is ill-formed.
</dd>
<dt>Returns:</dt>
<dd>A pointer to the value stored in the variant, if <code>v != nullptr</code> and <code>v-&gt;index() == I</code>. Otherwise, returns <code>nullptr</code>.
</dd>
</dl>


<p class="function">
<code>
template &lt;class T, class... Types&gt;<br/>
&nbsp; constexpr add_pointer_t&lt;T&gt; get_if(variant&lt;Types...&gt;* v) noexcept;<br/>
template &lt;class T, class... Types&gt;<br/>
&nbsp; constexpr add_pointer_t&lt;const T&gt; get_if(const variant&lt;Types...&gt;* v) noexcept;
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
<dd>The type <code>T</code> occurs exactly once in <code>Types...</code>, and <code>T</code> is not a possibly <em>cv</em>-qualified <code>void</code>. Otherwise, the program is ill-formed.</dd>
<dt>Effects:</dt>
<dd>Equivalent to <code>return get_if&lt;T_i&&gt;(v)</code> with <code>i</code> being the zero-based index of <code>T</code> in <code>Types...</code>.</dd>
</dl>


<h4 id="relational-operators">?.6 Relational operators <span class="section_name">[variant.relops]</span></h4>

<p class="function">
<code>
template &lt;class... Types&gt; constexpr bool operator==(const variant&lt;Types...&gt;&amp; v, const variant&lt;Types...&gt;&amp; w);
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
<dd><code>get&lt;i&gt;(v) == get&lt;i&gt;(w)</code> is a valid expression returning a type that is convertible to <code>bool</code>, for all <code>i</code>.
</dd>
<dt>Effects:</dt>
<dd>Equivalent to <code>return (v.valueless_by_exception() &amp;&amp; w.valueless_by_exception()) || (v.index() == w.index() &amp;&amp; get&lt;i&gt;(v) == get&lt;i&gt;(w))</code> with <code>i</code> being <code>v.index()</code>, otherwise <code>false</code>.
</dd>
</dl>

<p class="function">
<code>
template &lt;class... Types&gt; constexpr bool operator!=(const variant&lt;Types...&gt;&amp; v, const variant&lt;Types...&gt;&amp; w);
</code>
</p>
<dl class="attribute">
<dt>Returns:</dt>
<dd><code>!(v == w)</code>.
</dd>
</dl>

<p class="function">
<code>
template &lt;class... Types&gt; constexpr bool operator&lt;(const variant&lt;Types...&gt;&amp; v, const variant&lt;Types...&gt;&amp; w);
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
<dd><code>get&lt;i&gt;(v) &lt; get&lt;i&gt;(w)</code> is a valid expression returning a type that is convertible to <code>bool</code>.
</dd>
<dt>Effects:</dt>
<dd>Equivalent to <code>return (v.index() &lt; w.index()) || (v.index() == w.index() &amp;&amp; !v.valueless_by_exception() &amp;&amp; get&lt;i&gt;(v) &lt; get&lt;i&gt;(w))</code> with <code>i</code> being <code>v.index()</code>, otherwise <code>false</code>.
</dd>
</dl>

<p class="function">
<code>
template &lt;class... Types&gt; constexpr bool operator&gt;(const variant&lt;Types...&gt;&amp; v, const variant&lt;Types...&gt;&amp; w);
</code>
</p>
<dl class="attribute">
<dt>Returns:</dt>
<dd><code>w &lt; v</code>.
</dd>
</dl>

<p class="function">
<code>
template &lt;class... Types&gt; constexpr bool operator&lt;=(const variant&lt;Types...&gt;&amp; v, const variant&lt;Types...&gt;&amp; w);
</code>
</p>
<dl class="attribute">
<dt>Returns:</dt>
<dd><code>!(v &gt; w)</code>.
</dd>
</dl>

<p class="function">
<code>
template &lt;class... Types&gt; constexpr bool operator&gt;=(const variant&lt;Types...&gt;&amp; v, const variant&lt;Types...&gt;&amp; w);
</code>
</p>
<dl class="attribute">
<dt>Returns:</dt>
<dd><code>!(v &lt; w)</code>
</dd>
</dl>


<h4 id="visitation">?.7 Visitation <span class="section_name">[variant.visit]</span></h4>

<p class="function">
<code>
template &lt;class Visitor, class... Variants&gt;<br/>
&nbsp; constexpr <em>see below</em> visit(Visitor&amp;&amp; vis, Variants&amp;&amp;... vars);
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
<dd>The expression in the Effects element must be a valid expression of the same type, for all combinations of alternative types of all variants.
</dd>
<dt>Effects:</dt>
<dd>Let <code>is...</code> be <code>vars.index()...</code>. Returns <code>INVOKE(forward&lt;Visitor&gt;(vis), get&lt;is&gt;(forward&lt;Variants&gt;(vars))...);</code>.
</dd>
  <dt>Remarks:</dt>
  <dd>The return type is the <code>common_type</code> of all possible <code>INVOKE</code> expressions of the Effects element.</dd>
  <dt>Throws:</dt>
  <dd><code>bad_variant_access</code> if any <code>variant</code> in <code>vars</code> is <code>valueless_by_exception()</code>.</dd>
<dt>Complexity:</dt>
<dd>For <code>sizeof...(Variants)</code> being <code>1</code>, the invocation of the callable must be implemented in constant time, i.e. it must not depend on <code>sizeof...(Types)</code>. For <code>sizeof...(Variants)</code> greater <code>1</code>, the invocation of the callable has no complexity requirements.
</dd>
</dl>


<h4>?.8 Class <code>monostate</code> <span class="section_name">[variant.monostate]</span></h4>

<pre>
<code>
struct monostate{};
</code>
</pre>

<p>The class <code>monostate</code> can serve as a first alternative type for a <code>variant</code> to make the <code>variant</code> type default constructible.</p>

  
<h4>?.9 <code>monostate</code> relational operators <span class="section_name">[variant.monostate.relops]</span></h4>

<p class="function">
<code>
constexpr bool operator&lt;(monostate, monostate) noexcept
  { return false; }<br/>
constexpr bool operator&gt;(monostate, monostate) noexcept
  { return false; }<br/>
constexpr bool operator&lt;=(monostate, monostate) noexcept
  { return true; }<br/>
constexpr bool operator&gt;=(monostate, monostate) noexcept
  { return true; }<br/>
constexpr bool operator==(monostate, monostate) noexcept
  { return true; }<br/>
constexpr bool operator!=(monostate, monostate) noexcept
  { return false; }<br/>
</code></p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>Compare two <code>monostate</code> objects. <code>monostate</code> object have only a single state; they thus always compare equal.</dd>
</dl>

  
<h4>?.10 Specialized algorithms <span class="section_name">[variant.specalg]</span></h4>

<p class="function">
<code>
template &lt;class... Types&gt; void swap(variant&lt;Types...&gt;&amp; v, variant&lt;Types...&gt;&amp; w) noexcept(<em>see below</em>);
</code>
</p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>Calls <code>v.swap(w)</code>.</dd>
<dt>Remarks:</dt>
<dd>The expression inside <code>noexcept</code> is equivalent to <code>noexcept(v.swap(w))</code>.
</dd>
</dl>


<h4>?.11 Class <code>bad_variant_access</code> <span class="section_name">[variant.bad_variant_access]</span></h4>
<pre>
<code>
class bad_variant_access : public exception {
public:
  bad_variant_access() noexcept;
  const char* what() const noexcept override;
};
</code>
</pre>
<p>Objects of type <code>bad_variant_access</code> are thrown to report invalid accesses to the value of a <code>variant</code> object.

<p class="function">
<code>
bad_variant_access() noexcept;
</code><p>
<dl class="attribute">
<dt>Effects:</dt>
<dd>Constructs a <code>bad_variant_access</code> object.
</dd>
  <dt>Postconditions:</dt>
  <dd>what() returns an implementation-defined NTBS.</dd>
</dl>

<p class="function">
<code>
const char* what() const noexcept override;
</code>
</p>
<dl class="attribute">
<dt>Returns:</dt>
<dd>an implementation-defined NTBS.</dd>
</dl>

  <h4>?.12 <code>tuple</code> interface to class template <code>variant</code> <span class="section_name">[variant.tuple]</span></h4>

<p class="function">
<code>
template &lt;class... Types&gt;<br/>
struct tuple_size&lt;variant&lt;Types...&gt;&gt;<br/>
&nbsp; : integral_constant&lt;size_t, sizeof...(Types)&gt; { };
</code>
</p>

<p class="function">
<code>
tuple_element&lt;I, variant&lt;Types...&gt;&gt;::type
</code>
</p>
<dl class="attribute">
<dt>Value:</dt>
<dd>The type <code>T_I</code>.</dd>
</dl>

<h4 id="hash-support">?.13 Hash support <span class="section_name">[variant.hash]</span></h4>
<p class="function">
<code>
template &lt;class... Types&gt; struct hash&lt;experimental::variant&lt;Types...&gt;&gt;;
</code>
</p>
<p>The template specialization <code>hash&lt;T&gt;</code> shall meet the requirements of class template <code>hash</code> (C++14 &sect;20.9.13) for all <code>T</code> in <code>Types</code>. The template specialization <code>hash&lt;variant&lt;Types...&gt;&gt;</code> shall meet the requirements of class template <code>hash</code>.
</p>
<p class="function">
<code>
template &lt;&gt; struct hash&lt;experimental::monostate&gt;;
</code>
</p>
<p>The template specialization <code>hash&lt;monostate&gt;</code> shall meet the requirements of class template <code>hash</code>.
</p>


<h4 id="alloc-traits">?.14 Allocator-related traits <span class="section_name">[variant.traits]</span></h4>
<p class="function">
<code>
template &lt;class R, class Alloc&gt;<br/>
&nbsp; struct uses_allocator&lt;experimental::variant&lt;R&gt;, Alloc&gt; : true_type { };
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
  <dd><code>Alloc</code> shall be an <code>Allocator</code> (17.6.3.5).</dd>
<dt>[<em>Note:</em></dt>
<dd>Specialization of this trait informs other library components that <code>variant</code> can be constructed with an allocator, even though it does not have a nested <code>allocator_type</code>. <em>&mdash; end note</em>]</dd>
</dl>

</blockquote>


<h2 id="conclusion">Conclusion</h2>
<p>A variant has proven to be a useful tool. This paper proposes the necessary ingredients.</p>
<h2 id="acknowledgments">Acknowledgments</h2>
<p>Thank you, Nevin ":-)" Liber, for bringing sanity to this proposal. Agust&iacute;n K-ballo Berg&eacute;  and Antony Polukhin provided very valuable feedback, criticism and suggestions. Thanks also to Vincenzo Innocente and Philippe Canal for their comments.</p>
<h2 id="references" class="references unnumbered">References</h2>
<div id="ref-N4335">
<p>1. <em>Working Draft, Technical Specification on C++ Extensions for Library Fundamentals</em>. N4335</p>
</div>
<div id="ref-PERFECTINIT">
<p>2. <em>Improving pair and tuple, revision 2</em>. N4064</p>
</div>
</body>
</html>
