<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="author" content="P0088R2, 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;
}
ins.edit { text-decoration: none;
    border-bottom: 1px solid #0000c1;
    color: #0000c1;
    line-height: 1.4em;
    background-color: #eeeeff;
}
del.edit {
  text-decoration: line-through;
    border-bottom: 1px solid #0000c1;
    color: #0000c1;
    line-height: 1.4em;
    background-color: #eeeeff;
}
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 for C++17 (v7).</title>
</head>

<body>
<table class="header">
    <tr><td>Document Number:</td> <td>P0088R2, ISO/IEC JTC1 SC22 WG21</td></tr>
  <tr><td>Audience:</td><td>LWG</td></tr>
    <tr><td>Date:</td><td>2016-03-21</td></tr>
    <tr><td>Author:</td><td>Axel Naumann (axel@cern.ch)</td></tr>
</table>
<h1>Variant: a type-safe union for C++17 (v7).</h1>

    <h2>Table of Contents</h2>
<nav id="TOC">
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#history">Revision history</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++<b><em>17</em></b> needs a type-safe union:</p>
  
<p>Lets not make the same mistake we made with <code>std::optional</code> by putting this library into a TS. We waited three years where no substantial feedback or discussion occurred, and then moved it into the IS virtually unchanged. Meanwhile, the C++ community suffered, and we continue to suffer from lack of this essential vocabulary type in interfaces.</p>

<p>The implications of the consensus <code>variant</code> design are well understood and have been explored over several LEWG discussions, over a thousand emails, a joint LEWG/EWG session, and not to mention 12 years of experience with Boost and other libraries. The last major change made to the proposal was non-breaking and added exception throws where previously there was undefined behavior. Since then, all suggested modifications have been cosmetic, rehashes of older discussions, or would be handled just as well by defect resolutions.</p>

<p>The C++ community should not wait three years for a widely useful library that is already done, fits its purpose, and has had such extensive review. There is a low chance that we will regret including variant in C++17, but a high chance that we will regret omitting it.</p>
  
  <p>This proposal 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>

<h2 id="history">Revision history</h2>

<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>

<h3 id="differences-to-revision-6-p0088r1">Differences to revision 6 (P0088R1)</h3>
<ul>
<li>Bring back <code>tuple_not_found</code> that got removed by mistake. Call it <code>variant_npos</code>.</li>
<li>Implement wording comments from Jacksonville LWG.</li>
  <li>Rename <code>tuple_size</code> to <code>variant_size</code>, <code>tuple_element</code> to <code>variant_alternative</code> to clarify that this is not tuple-like. This avoids a clash with structured binding. The committee seems to have changed its common mind regarding these templates, reverting LEWG's decision from the first revision.</li>
  <li>Do not implicitly force the <code>variant</code> <code>valueless_by_exception</code> if an exception is thrown during emplace / construction; merely state that it <em>might</em> become <code>valueless_by_exception</code>.</li>
  <li>Reflect LEWG's updated recommended shipping vehicle (was TS, now C++17).</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>variant_npos</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 C++ Working Paper. Grayish background indicates proposed wording. Blue markup indicates changes to the previous revision, with <ins class="edit">insertions</ins> and <del class="edit">deletions</del> signaled in an obvious way.</p>    

  
  
  <del class="edit">
<h3>Header &lt;experimental/tuple&gt;</h3>
<ins>Insertions</ins> and <del>deletions</del> mark the parts to be inserted into / deleted from existing wording.

<blockquote class="std">
<pre><em><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4529.html#header.tuple.synop">3.2.1</a> Header &lt;experimental/tuple&gt; synopsis</em>

#include &lt;tuple&gt;

namespace std {
namespace experimental {
inline namespace fundamentals_vXXXX {

  <em>// See C++14 &sect;20.4.2.5, tuple helper classes</em>
  template &lt;class T&gt; constexpr size_t tuple_size_v
    = tuple_size&lt;T&gt;::value;

<ins>
  <em>// 3.2.2, tuple_find</em>
  static constexpr size_t tuple_not_found = -1;

</ins>
} // namespace fundamentals_vXXXX
} // namespace experimental
} // namespace std
</pre></blockquote>

The definition of <code>tuple_not_found</code> shall belong to <code>[tuple.helper]</code>; it shall not get a new section name.
</del>
  


<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;<del class="edit">experimental/</del>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>A variant object holds and manages 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;<del class="edit">experimental/</del>variant&gt;</code> synopsis <span class="section_name">[variant.synopsis]</span></h4>
<pre>
<code>
namespace std {
<del class="edit">namespace experimental {
inline namespace fundamentals_vXXXX {</del>
  <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{<ins class="edit"> explicit in_place_type_t() = default; </ins>};
  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{<ins class="edit"> explicit in_place_index_t() = default; </ins>};
  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 <del class="edit">tuple_element_t</del><ins class="edit">variant_alternative_t</ins>&lt;I, variant&lt;Types...&gt;&gt;&amp;
    get(variant&lt;Types...&gt;&amp;);
  template &lt;size_t I, class... Types&gt;
    constexpr <del class="edit">tuple_element_t</del><ins class="edit">variant_alternative_t</ins>&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 <del class="edit">tuple_element_t</del><ins class="edit">variant_alternative_t</ins>&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 <del class="edit">tuple_element_t</del><ins class="edit">variant_alternative_t</ins>&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;<del class="edit">tuple_element_t</del><ins class="edit">variant_alternative_t</ins>&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 <del class="edit">tuple_element_t</del><ins class="edit">variant_alternative_t</ins>&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;
  
<del class="edit">} // namespace fundamentals_vXXXX
} // namespace experimental</del>

  <em>// ?.12,</em> <del class="edit">tuple</del> <em><del class="edit">interface</del></em><ins class="edit">variant<em> helper classes</em></ins>
<ins class="edit">  template &lt;class T&gt; struct variant_size; <em>// undefined</em>
  template &lt;class T&gt; struct variant_size&lt;const T&gt;;
  template &lt;class T&gt; struct variant_size&lt;volatile T&gt;;
  template &lt;class T&gt; struct variant_size&lt;const volatile T&gt;;
  template &lt;class T&gt; constexpr size_t variant_size_v
    = variant_size&lt;T&gt;::value;
</ins>
  template &lt;class... Types&gt;
    struct <del class="edit">tuple_size</del><ins class="edit">variant_size</ins>&lt;variant&lt;Types...&gt;&gt;;
<ins class="edit">
  template &lt;size_t I, class T&gt; struct variant_alternative; <em>// undefined</em>
  template &lt;size_t I, class T&gt; struct variant_alternative&lt;I, const T&gt;;
  template &lt;size_t I, class T&gt; struct variant_alternative&lt;I, volatile T&gt;;
  template &lt;size_t I, class T&gt; struct variant_alternative&lt;I, const volatile T&gt;;
  template &lt;size_t I, class T&gt;
    using variant_alternative_t = typename variant_alternative&lt;I, T&gt;::type;
</ins>
  template &lt;size_t I, class... Types&gt;
    struct <del class="edit">tuple_element</del><ins class="edit">variant_alternative</ins>&lt;I, variant&lt;Types...&gt;&gt;;
<ins class="edit">
  static constexpr size_t variant_npos = -1;
</ins>
  <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>
  <ins class="edit">template &lt;class T, class Alloc&gt; struct uses_allocator;</ins>
  template &lt;class... Types, class Alloc&gt;
  struct uses_allocator&lt;experimental::variant&lt;Types...&gt;, Alloc&gt;;
} // namespace std
</code>
</pre>

<del class="edit"><p>Including this header also makes the following declarations 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;;

static constexpr size_t tuple_not_found = -1;
</code></pre>
</del>

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

    <em>// ?.3.1 Constructors</em>
    constexpr variant() noexcept(<em>see below</em>);
    variant(const variant&amp;)<del class="edit"> noexcept(<em>see below</em>)</del>;
    variant(variant&amp;&amp;) noexcept(<em>see below</em>);

    template &lt;class T&gt; constexpr variant(T&amp;&amp;)<ins class="edit"> noexcept(<em>see below</em>)</ins>;

    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;<del class="edit"> a</del>, const variant&amp;);
    template &lt;class Alloc&gt;
      variant(allocator_arg_t, const Alloc&amp;<del class="edit"> a</del>, 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>);
<del class="edit">
  private:
    aligned_storage&lt;Unspecified&gt;::type storage; // <em>exposition only</em>
    size_t value_type_index; // exposition only
</del>
  };
<del class="edit">} // namespace fundamentals_vXXXX
} // namespace experimental</del>
} // 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 (possibly <em>cv</em>-qualified) object types, (possibly <em>cv</em>-qualified) void, or references. [<em>Note:</em> Implementations could decide to store references in a <del class="edit">reference_</del><ins class="edit"> </ins>wrapper. <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>constexpr</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 <del class="edit">from the value contained in <code>w</code></del><ins class="edit">with <code>get&lt;j&gt;(w)</code>, where <code>j</code> is <code>w.index()</code></ins>. 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 <del class="edit"><code>std::forward&lt;T_j&gt;(get&lt;j&gt;(w))</code></del><ins class="edit"><code>get&lt;j&gt;(std::move(w))</code></ins>, 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)<ins class="edit"> noexcept(<em>see below</em>)</ins>;
</code>
</p>
  <ins class="edit">
    Let <code>T_j</code> be a type that is determined as follows: build an imaginary function <code><em>FUN</em>(T_i)</code> for each alternative type <code>T_i</code>. The overload <code><em>FUN</em>(T_j)</code> selected by regular overload resolution for the expression <code><em>FUN</em>(std::forward&lt;T&gt;(t))</code> defines the alternative <code>T_j</code> which is the type of the contained value after construction.</ins>
<dl class="attribute">
  <dt><del class="edit">Requires:</del></dt>
  <dd><del class="edit">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> <del class="edit">that will be activated by the call to this constructor</del><ins class="edit">which is the type of the contained value after construction</ins>. [<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>]
  </del></dd>

<dt>Effects:</dt>
  <dd>Initializes <code>*this</code> to hold the alternative type <code>T_j</code><del class="edit"> as selected by the imaginary function overload resolution described above,</del> 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><del class="edit">, with <code>T_j</code> selected by the imaginary function overload resolution described above</del>.
</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><ins class="edit">, unless <code>is_constructible_v&lt;T_j, T&amp;&amp;&gt;</code> is <code>true</code>, and unless the expression <code><em>FUN</em>(std::forward&lt;T&gt;(t))</code> (with <code>FUN</code> being the above-mentioned set of imaginary functions) is <del class="edit">valid according to regular overload resolution</del><ins class="edit">well formed</ins>.
   [<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>]
  The expression inside <code>noexcept</code> is equivalent to <code>is_nothrow_constructible_v&lt;T_j, T&amp;&amp;&gt;</code>. </ins>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 <del class="edit">as if constructing an object </del>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 occurrence 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> holds a value, there is 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><del class="edit">
<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></del>
  </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>.
    <ins class="edit">
      <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 construction (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 construction, the <code>variant</code> will hold no value.</li>
  </ul>
  </ins>
  </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> holds a value, there is 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 <del class="edit"><code>std::forward&lt;T_j&gt;(get&lt;j&gt;(rhs))</code></del><ins class="edit">get&lt;j&gt;(std::move(rhs))</ins> 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 <del class="edit"><code>std::forward&lt;T_j&gt;(get&lt;j&gt;(rhs))</code></del><ins class="edit">get&lt;j&gt;(rhs)</ins> with <code>j</code> being <code>rhs.index()</code>.</li>
</ul><del class="edit">
  <br/>
  If an exception is thrown during the call to <code>T_j</code>'s move construct<del class="edit">or</del><ins class="edit">ion</ins> (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>.
</del>
</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>.
  <ins class="edit">
      If an exception is thrown during the call to <code>T_j</code>'s move construct<del class="edit">or</del><ins class="edit">ion</ins> (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>.
  </ins>
</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>
<ins class="edit">
    Let <code>T_j</code> be a type that is determined as follows: build an imaginary function <code><em>FUN</em>(T_i)</code> for each alternative type <code>T_i</code>. The overload <code><em>FUN</em>(T_j)</code> selected by regular overload resolution for the expression <code><em>FUN</em>(std::forward&lt;T&gt;(t))</code> defines the alternative <code>T_j</code> which is the type of the contained value after assignment.</ins><dl class="attribute">
<dt><del class="edit">Requires:</del></dt>
  <dd><del class="edit">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> <del class="edit">that will be activated by the assignment</del><ins class="edit">which is the type of the contained value after assignment</ins>. [<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>]
    </del></dd>
<dt>Effects:</dt>
  <dd><del class="edit">No effect if <code>decay_t&lt;T&gt;(t)</code> is <code>void</code>. </del>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>.
    <del class="edit">
<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 <del class="edit">will</del><ins class="edit">might</ins> not hold a value.
      </del>
</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><ins class="edit">, unless <code>is_assignable_v&lt;T_j<ins class="edit">&amp;</ins>, T&amp;&amp;&gt; &amp;&amp; is_constructible_v&lt;T_j, T&amp;&amp;&gt;</code> is <code>true</code>, and unless the expression <code><em>FUN</em>(std::forward&lt;T&gt;(t))</code> (with <code>FUN</code> being the above-mentioned set of imaginary functions) is <del class="edit">valid according to regular overload resolution</del><ins class="edit">well formed</ins>.
   [<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>]
  </ins> The expression inside <code>noexcept</code> is equivalent to: <code>is_nothrow_assignable_v&lt;T_<del class="edit">i</del><ins class="edit">j&amp;</ins>, T&amp;&amp;&gt; &amp;&amp; is_nothrow_constructible_v&lt;T_<del class="edit">i</del><ins class="edit">j</ins>, T&amp;&amp;&gt;</code><del class="edit"> for all <code>i</code></del>.
  <ins class="edit">
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 <del class="edit">will</del><ins class="edit">might</ins> not hold a value.
      </ins>

</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><del class="edit">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>.</del>
    <ins class="edit">Equivalent to <code>emplace&lt;I&gt;(std::forward&lt;Args&gt;(args)...)</code> where <code>I</code> is the zero-based index of <code>T</code> in <code>Types...</code>.</ins>
    <del class="edit"> If an exception is thrown during the initialization of the contained value, the <code>variant</code> <del class="edit">will</del><ins class="edit">might</ins> not hold a value.</del>
</dd>
<dt>Postcondition:</dt>
<dd><code>holds_alternative&lt;T&gt;(*this)</code> is <code>true</code>.
</dd>
<dt><del class="edit">Throws:</del></dt>
  <dd><del class="edit">Any exception thrown during the initialization of the contained value.</del>
</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><del class="edit">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>.</del>
    <ins class="edit">Equivalent to <code>emplace&lt;I&gt;(il, std::forward&lt;Args&gt;(args)...)</code> where <code>I</code> is the zero-based index of <code>T</code> in <code>Types...</code>.</ins>
  <del class="edit">
  If an exception is thrown during the initialization of the contained value, the <code>variant</code> <del class="edit">will</del><ins class="edit">might</ins> not hold a value.</del>
</dd>
<dt>Postcondition:</dt>
<dd><code>holds_alternative&lt;T&gt;(*this)</code> is <code>true</code>.
</dd>
<dt><del class="edit">Throws:</del></dt>
<dd><del class="edit">Any exception thrown during the initialization of the contained value</del>.
</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>.<del class="edit">
  If an exception is thrown during the initialization of the contained value, the <code>variant</code> <del class="edit">will</del><ins class="edit">might</ins> not hold a value.</del>
</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>.<ins class="edit">
  If an exception is thrown during the initialization of the contained value, the <code>variant</code> <del class="edit">will</del><ins class="edit">might</ins> not hold a value.</ins>
</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>.<del class="edit">
  If an exception is thrown during the initialization of the contained value, the <code>variant</code> <del class="edit">will</del><ins class="edit">might</ins> not hold a value.</del>
</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>.<ins class="edit">
  If an exception is thrown during the initialization of the contained value, the <code>variant</code> <del class="edit">will</del><ins class="edit">might</ins> not hold a value.</ins>
</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 <ins class="edit"><code>false</code> if and only if the <code>variant</code> holds a value</ins><del class="edit"> whether the <code>variant</code> holds a value (returns <code>false</code>)</del>. [<em>Note:</em>
A <code>variant</code> <del class="edit">will</del><ins class="edit">might</ins> 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>variant_npos</code>. Otherwise, returns the <ins class="edit">zero-based </ins>index of the <del class="edit">currently active </del>alternative<ins class="edit"> of the contained value</ins>.
</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> where <code>i</code> is <code>index()</code>. Otherwise,</li>
  <li>exchanges values of <code>rhs</code> and <code>*this</code>.</li></ul>
<del class="edit">
  <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 states of the contained values of <code><ins class="edit">*</ins>this</code> and of <code>rhs</code> are 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 states of the values of <code><ins class="edit">*</ins>this</code> and of <code>rhs</code> are determined by the exception safety guarantee of <code>variant</code>'s move constructor and <ins class="edit">move </ins>assignment operator.</del>
</dd>
<dt>Throws:</dt>
<dd>Any exception 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 <ins class="edit">move </ins>assignment operator.
</dd>
  <dt>Remarks:</dt>
  <dd>This function shall not participate in overload resolution unless <ins class="edit"><code>is_swappable_v&lt;T_i&gt;</code> is <code>true</code> for all <code>i</code></ins><del class="edit">all alternative types satisfy the <code>Swappable</code> requirements (17.6.3.2) with the corresponding alternative in <code>rhs</code></del>.
<ins class="edit">
  If an exception is thrown during the call to function <code>swap(get&lt;i&gt;(*this), get&lt;i&gt;(rhs))</code>, the states of the contained values of <code><ins class="edit">*</ins>this</code> and of <code>rhs</code> are 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 states of the values of <code><ins class="edit">*</ins>this</code> and of <code>rhs</code> are determined by the exception safety guarantee of <code>variant</code>'s move constructor and <ins class="edit">move </ins>assignment operator.</ins>
  </dd>
</dl>

<h4>?.4 In-place construction <span class="section_name">[variant.in_place]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; struct in_place_type_t{<ins class="edit"> explicit in_place_type_t() = default; </ins>};<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{<ins class="edit"> explicit in_place_index_t() = default; </ins>};<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 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 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><ins class="edit"><code>true</code> if <code>index()</code> is equal to </ins>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 <del class="edit">tuple_element_t</del><ins class="edit">variant_alternative_t</ins>&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 <del class="edit">tuple_element_t</del><ins class="edit">variant_alternative_t</ins>&lt;I, variant&lt;Types...&gt;&gt;&amp;&amp; get(variant&lt;Types...&gt;&amp;&amp; v);<del class="edit"> <em>// Note A</em></del><br/>
template &lt;size_t I, class... Types&gt;<br/>
&nbsp; constexpr <del class="edit">tuple_element_t</del><ins class="edit">variant_alternative_t</ins>&lt;I, variant&lt;Types...&gt;&gt; const&amp; get(const variant&lt;Types...&gt;&amp; v);<del class="edit"> // Note B</del><br/>
template &lt;size_t I, class... Types&gt;<br/>
&nbsp; constexpr <del class="edit">tuple_element_t</del><ins class="edit">variant_alternative_t</ins>&lt;I, variant&lt;Types...&gt;&gt; const&amp;&amp; get(const variant&lt;Types...&gt;&amp;&amp; v);<del class="edit"> // Notes A and B
</del></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>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><del class="edit">[<em>Note A:</em></del></dt>
  <dd><del class="edit">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>]
    </del></dd>
  <dt><del class="edit">[<em>Note B:</em></del></dt>
  <dd>
    <del class="edit">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>]</del>
  </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 (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;<del class="edit">tuple_element_t</del><ins class="edit">variant_alternative_t</ins>&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 <del class="edit">tuple_element_t</del><ins class="edit">variant_alternative_t</ins>&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 (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;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><del class="edit">, otherwise <code>false</code></del>.
</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><del class="edit">Returns</del><ins class="edit">Effects</ins>:</dt>
  <dd><ins class="edit">Equivalent to <code>return </code></ins><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>, for all <code>i</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><del class="edit">, otherwise <code>false</code></del>.
</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><del class="edit">Returns</del><ins class="edit">Effects</ins>:</dt>
<dd><ins class="edit">Equivalent to <code>return </code></ins><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><del class="edit">Returns</del><ins class="edit">Effects</ins>:</dt>
<dd><ins class="edit">Equivalent to <code>return </code></ins><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><del class="edit">Returns</del><ins class="edit">Effects</ins>:</dt>
<dd><ins class="edit">Equivalent to <code>return </code></ins><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 and value category, for all combinations of alternative types of all variants.<ins class="edit"> Otherwise, the program is ill-formed.</ins>
</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 <del class="edit"><code>common_type</code></del><ins class="edit">common type</ins> 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) &lt;= 1</code>, the invocation of the callable object must be implemented in constant time, i.e. it must not depend on <code>sizeof...(Types)</code>. For <code>sizeof...(Variants) &gt; 1</code>, the invocation of the callable object 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>[<em>Note:</em></dt>
<dd><code>monostate</code> object have only a single state; they thus always compare equal.<em>&mdash; end note</em>]
  </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><del class="edit">Calls</del><ins class="edit">Equivalent to</ins> <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;
  virtual const char* what() const noexcept;
};
</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><del class="edit">Postconditions:</del></dt>
  <dd><del class="edit">what() returns an implementation-defined NTBS.</del></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 <del class="edit"><code>tuple</code> interface to class template <code>variant</code></del><ins class="edit"><code>variant</code> helper classes</ins> <span class="section_name"><del class="edit">[variant.tuple]</del><ins class="edit">[variant.helper]</ins></span></h4>

<ins class="edit">
<p class="function">
<code>
template &lt;class T&gt; struct variant_size;<br/>
</code>
</p>
  <dl class="attributes">
    <dt>Remarks:</dt>
  <dd>All specializations of <code>variant_size&lt;T&gt;</code> shall meet the <code>UnaryTypeTrait</code> requirements (20.10.1) with a <code>BaseCharacteristic</code> of <code>integral_constant&lt;size_t, N&gt;</code> for some <code>N</code>.</dd>
  </dl>

<p class="function">
<code>
template &lt;class T&gt; class variant_size&lt;const T&gt;;<br/>
template &lt;class T&gt; class variant_size&lt;volatile T&gt;;<br/>
template &lt;class T&gt; class variant_size&lt;const volatile T&gt;;
</code>
</p>
  <dl class="attributes">
    <dt></dt>
  <dd>Let <code>VS</code> denote <code>variant_size&lt;T&gt;</code> of the <em>cv</em>-unqualified type <code>T</code>. Then each of the three templates shall meet the <code>UnaryTypeTrait</code> requirements (20.10.1) with a <code>BaseCharacteristic</code> of
  <code>integral_constant&lt;size_t, VS::value&gt;</code>.</dd>
    </dl>
</ins>

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

<ins class="edit">
<p class="function">
<code>
template &lt;size_t I, class T&gt; class variant_alternative&lt;I, const T&gt;;<br/>
template &lt;size_t I, class T&gt; class variant_alternative&lt;I, volatile T&gt;;<br/>
template &lt;size_t I, class T&gt; class variant_alternative&lt;I, const volatile T&gt;;
</code>
</p>
  <dl class="attributes">
    <dt></dt>
  <dd>Let <code>VA</code> denote <code>variant_alternative&lt;I, T&gt;</code> of the <em>cv</em>-unqualified type <code>T</code>. Then each of the three templates shall meet the <code>TransformationTrait</code> requirements (20.10.1) with a member typedef <code>type</code> that names
the following type:
    <ul>
<li>for the first specialization, <code>add_const_t&lt;VA::type&gt;</code>,</li>
<li>for the second specialization, <code>add_volatile_t&lt;VA::type&gt;</code>, and</li>
<li>for the third specialization, <code>add_cv_t&lt;VA::type&gt;</code>.</li>
</ul>
    </dd>
    </dl>
</ins>

<p class="function">
<code>
<del class="edit">tuple_element</del><ins class="edit">variant_alternative</ins>&lt;I, variant&lt;Types...&gt;&gt;::type
</code>
</p>
<dl class="attribute">
<dt><ins class="edit">Requires:</ins></dt>
  <dd><ins class="edit"><code>I &lt; sizeof...(Types)</code></ins></dd>
<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;<del class="edit">experimental::</del>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;<del class="edit">experimental::</del>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;<del class="edit">experimental::</del>monostate&gt;;
</code>
</p>
  <p>The template specialization <code>hash&lt;<del class="edit">experimental::</del>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... Types, class Alloc&gt;<br/>
  &nbsp; struct uses_allocator&lt;<del class="edit">experimental::</del>variant&lt;Types...&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>
