<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <meta name="generator" content="pandoc" />
  <title></title>
  <style type="text/css">code{white-space: pre;}</style>
  <style type="text/css">
div.sourceCode { overflow-x: auto; }
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
  margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
code > span.dt { color: #902000; } /* DataType */
code > span.dv { color: #40a070; } /* DecVal */
code > span.bn { color: #40a070; } /* BaseN */
code > span.fl { color: #40a070; } /* Float */
code > span.ch { color: #4070a0; } /* Char */
code > span.st { color: #4070a0; } /* String */
code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
code > span.ot { color: #007020; } /* Other */
code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
code > span.fu { color: #06287e; } /* Function */
code > span.er { color: #ff0000; font-weight: bold; } /* Error */
code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
code > span.cn { color: #880000; } /* Constant */
code > span.sc { color: #4070a0; } /* SpecialChar */
code > span.vs { color: #4070a0; } /* VerbatimString */
code > span.ss { color: #bb6688; } /* SpecialString */
code > span.im { } /* Import */
code > span.va { color: #19177c; } /* Variable */
code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code > span.op { color: #666666; } /* Operator */
code > span.bu { } /* BuiltIn */
code > span.ex { } /* Extension */
code > span.pp { color: #bc7a00; } /* Preprocessor */
code > span.at { color: #7d9029; } /* Attribute */
code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
  </style>
</head>
<body>
<h1 id="the-case-for-a-language-based-variant">The Case for a Language Based Variant</h1>
<ul>
<li>Document number: P0095R0</li>
<li>Date: 2015-09-24</li>
<li>Project: ISO/IEC JTC1 SC22 WG21</li>
<li>Reply-to: David Sankel <script type="text/javascript">
<!--
h='&#x73;&#116;&#x65;&#108;&#108;&#x61;&#114;&#x73;&#x63;&#x69;&#x65;&#110;&#x63;&#x65;&#46;&#x63;&#x6f;&#x6d;';a='&#64;';n='&#100;&#x61;&#118;&#x69;&#100;';e=n+a+h;
document.write('<a h'+'ref'+'="ma'+'ilto'+':'+e+'" clas'+'s="em' + 'ail">'+e+'<\/'+'a'+'>');
// -->
</script><noscript>&#100;&#x61;&#118;&#x69;&#100;&#32;&#x61;&#116;&#32;&#x73;&#116;&#x65;&#108;&#108;&#x61;&#114;&#x73;&#x63;&#x69;&#x65;&#110;&#x63;&#x65;&#32;&#100;&#x6f;&#116;&#32;&#x63;&#x6f;&#x6d;</noscript></li>
</ul>
<h2 id="introduction">Introduction</h2>
<p>The current library-based variant proposals solve an important need<a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a>, but are they too complicated for novice users? We show that corner cases force novice users to understand the complexities of SFINE in basic usage, the pitfalls of using types as tags, and the difficulty of writing portable code using a library based variant. All of these problems point to the inclusion of a language-based variant feature in C++.</p>
<p>We propose a simple variant language feature called an enumerated union (<code>enum union</code>) with a basic pattern matching mechanism as a means to solve the aforementioned problems. The design is intended to be relatively easy for compiler implementers to add and flexible for future pattern matching extensions. We argue that an enumerated union complements a library-based variant in the same way that a <code>struct</code> compliments a library-based tuple.</p>
<p>The following snippet illustrates our proposed syntax.<a href="#fn2" class="footnoteRef" id="fnref2"><sup>2</sup></a></p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="co">// This enumerated union implements a value representing the various commands</span>
<span class="co">// available in a hypothetical shooter game.</span>
<span class="kw">enum</span> <span class="kw">union</span> command {
  std::size_t set_score; <span class="co">// Set the score to the specified value</span>
  std::monotype fire_missile; <span class="co">// Fire a missile</span>
  <span class="dt">unsigned</span> fire_laser; <span class="co">// Fire a laser with the specified intensity</span>
  <span class="dt">double</span> rotate; <span class="co">// Rotate the ship by the specified degrees.</span>
};

<span class="co">// Output a human readable string corresponding to the specified &#39;cmd&#39; command</span>
<span class="co">// to the specified &#39;stream&#39;.</span>
std::ostream&amp; <span class="kw">operator</span>&lt;&lt;( std::ostream&amp; stream, <span class="dt">const</span> command cmd ) {
  <span class="kw">switch</span>( cmd ) {
    <span class="kw">case</span> set_score value:
      stream &lt;&lt; <span class="st">&quot;Set the score to &quot;</span> &lt;&lt; value &lt;&lt; <span class="st">&quot;.</span><span class="ch">\n</span><span class="st">&quot;</span>;
    <span class="kw">case</span> fire_missile m:
      stream &lt;&lt; <span class="st">&quot;Fire a missile.</span><span class="ch">\n</span><span class="st">&quot;</span>;
    <span class="kw">case</span> fire_laser intensity:
      stream &lt;&lt; <span class="st">&quot;Fire a laser with &quot;</span> &lt;&lt; intensity &lt;&lt; <span class="st">&quot; intensity.</span><span class="ch">\n</span><span class="st">&quot;</span>;
    <span class="kw">case</span> rotate degrees:
      stream &lt;&lt; <span class="st">&quot;Rotate by &quot;</span> &lt;&lt; degrees &lt;&lt; <span class="st">&quot; degrees.</span><span class="ch">\n</span><span class="st">&quot;</span>;
  }
}

<span class="co">// Create a new command &#39;cmd&#39; that sets the score to &#39;10&#39;.</span>
command cmd = command::set_score( <span class="dv">10</span> );</code></pre></div>
<h2 id="motivation">Motivation</h2>
<h3 id="the-structtuple-and-enumerated-unionvariant-connection">The struct/tuple and enumerated-union/variant connection</h3>
<p>Basic <code>struct</code> types that have independently varying member variables<a href="#fn3" class="footnoteRef" id="fnref3"><sup>3</sup></a> have a close relationship to the <code>std::tuple</code> class. Consider the following two types:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="co">// point type as a struct</span>
<span class="kw">struct</span> point {
  <span class="dt">double</span> x;
  <span class="dt">double</span> y;
  <span class="dt">double</span> z;
};

<span class="co">// point type as a tuple</span>
<span class="kw">using</span> point = std::tuple&lt; <span class="dt">double</span>, <span class="dt">double</span>, <span class="dt">double</span> &gt;;</code></pre></div>
<p>It is clear that both <code>point</code> types above can represent a 3D mathematical point. The difference between these two types is, essentially, the tag which is used to discriminate between the three elements. In the <code>struct</code> case, an identifier is used (x, y, and z), and in the <code>std::tuple</code> case, an integer index is used (0, 1, and 2).</p>
<p>Although these two <code>point</code> implementations are more-or-less interchangeable, it is not always preferable to use a <code>struct</code> instead of a <code>std::tuple</code> nor vise-versa. In particular, we have the following general recommendations:</p>
<ol style="list-style-type: decimal">
<li>If the type needs to be created on the fly, as in generic code, a <code>std::tuple</code> must be used.</li>
<li>If an integer index isn't a clear enough identifier, a <code>struct</code> should be used.</li>
<li>Arguably, if inner types aren't essentially connected or if the structure is used only as the result of a function and is immediately used, a <code>std::tuple</code> is preferable.</li>
<li>In general, prefer to use a <code>struct</code> for improved code clarity.</li>
</ol>
<p>Some may argue that through use of <code>std::get</code>, which allows one to fetch a member of a tuple by type, one can achieve all the benefits of a <code>struct</code> by using a tuple instead. To take advantage of this feature, one needs to ensure that each inner type has its own distinct type. This can be accomplished through use of a wrapper. For example:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">struct</span> x { <span class="dt">double</span> value; };
<span class="kw">struct</span> y { <span class="dt">double</span> value; };
<span class="kw">struct</span> z { <span class="dt">double</span> value; };

<span class="kw">using</span> point = std::tuple&lt; x, y, z &gt;;</code></pre></div>
<p>Now one could use <code>std::get&lt;x&gt;</code> to fetch the 'x' value of the tuple, <code>std::get&lt;y&gt;</code> for 'y' and so on.</p>
<p>Should we use this approach everywhere and deprecate the use of <code>struct</code> in any context? In the author's opinion we should not. The use of wrapper types is much more complicated to both read and understand than a plain <code>struct</code>. For example, the wrapper types that were introduced, such as the 'x' type, make little sense outside of their corresponding tuples, yet they are peers to it in scope. Also, the heavy syntax makes it difficult to understand exactly what is intended by this code.</p>
<p>What does all this have to do with enumerated unions? The enumerated union is to <code>std::variant</code> as <code>struct</code> is to <code>std::tuple</code>. A variant type that represents a distance in an x direction, a y direction, <em>or</em> a z direction (mathematically called a &quot;copoint&quot;) has a similar look and feel to the <code>std::tuple</code> version of <code>point</code>.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">struct</span> x { <span class="dt">double</span> value; };
<span class="kw">struct</span> y { <span class="dt">double</span> value; };
<span class="kw">struct</span> z { <span class="dt">double</span> value; };

<span class="kw">using</span> copoint = std::variant&lt; x, y, z &gt;;</code></pre></div>
<p>This copoint implementation has the same drawbacks that the <code>std::tuple</code> implementation of points has. An enumerated union version of <code>copoint</code>, on the other hand, is easier to grok and doesn't require special tag types at all.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">enum</span> <span class="kw">union</span> copoint {
  <span class="dt">double</span> x;
  <span class="dt">double</span> y;
  <span class="dt">double</span> z;
};</code></pre></div>
<h3 id="sfine-in-basic-usage">SFINE in basic usage</h3>
<p>Some variation of the following example is common when illustrating a <code>std::variant</code> type:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">void</span> f( std::variant&lt; <span class="dt">double</span>, std::string&gt; v ) {
  <span class="kw">if</span>( std::holds_alternative&lt; <span class="dt">double</span> &gt;( v ) {
    std::cout &lt;&lt; <span class="st">&quot;Got a double &quot;</span> &lt;&lt; std::get&lt; <span class="dt">double</span> &gt;( v ) &lt;&lt; std::endl;
  }
  <span class="kw">else</span> {
    std::cout &lt;&lt; <span class="st">&quot;Got a string &quot;</span> &lt;&lt; std::get&lt; std::string &gt;( v ) &lt;&lt; std::endl;
  }
};</code></pre></div>
<p>This illustrates how quickly variants can be disassembled when they are simple, but it is hardly representative of how complex variant types are used. The primary problem in the above snippet is that there are no compile-time guarantees that ensure all of the <code>n</code> alternatives are covered. For the more general scenario, a <code>visit</code> function is provided.<a href="#fn4" class="footnoteRef" id="fnref4"><sup>4</sup></a></p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">struct</span> f_visitor {
  <span class="dt">void</span> <span class="kw">operator</span>()( <span class="dt">const</span> <span class="dt">double</span> d ) {
    std::cout &lt;&lt; <span class="st">&quot;Got a double &quot;</span> &lt;&lt; d &lt;&lt; std::endl;
  }
  <span class="dt">void</span> <span class="kw">operator</span>()( <span class="dt">const</span> std::string &amp; s ) {
    std::cout &lt;&lt; <span class="st">&quot;Got a string &quot;</span> &lt;&lt; s &lt;&lt; std::endl;
  }
};

<span class="dt">void</span> f( std::variant&lt; <span class="dt">double</span>, std::string &gt; v ) {
  std::visit( f_visitor(), v );
};</code></pre></div>
<p>Aside from the unsightly verbosity of the above code, the mechanism by which this works makes the visitor's <code>operator()</code> rules work by SFINE, which is a significant developer complication. Using a template parameter as part of a catch-all clause is going to necessarily produce strange error messages.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">struct</span> f_visitor {
  <span class="kw">template</span>&lt; <span class="kw">typename</span> T &gt;
  <span class="dt">void</span> <span class="kw">operator</span>()( <span class="dt">const</span> T &amp; t ) {
                                       <span class="co">// oops</span>
    std::cout &lt;&lt; <span class="st">&quot;I got something &quot;</span> &lt;&lt; t.size() &lt;&lt; std::endl;
  }
};

<span class="dt">void</span> f( std::variant&lt; <span class="dt">double</span>, std::string &gt; v ) {
  <span class="co">// Unhelpful error message awaits. Erroneous line won&#39;t be pointed out.</span>
  std::visit( f_visitor(), v );
};</code></pre></div>
<p>While the utility of type selection and SFINE for visitors is quite clear for advanced C++ developers, it presents significant hurdles for the beginning or even intermediate developer. This is especially true when it is considered that the <code>visit</code> function is the only way to guarantee a compilation error when all cases are not considered.</p>
<h3 id="duplicated-types-switching-on-the-numeric-index">Duplicated types: switching on the numeric index</h3>
<p>Using types as accessors with a <code>std::variant</code> works for many use cases, but not all. If there is a repeated type the only options are to either use wrapper types or to work with the real underlying discriminator, an integer index. To illustrate the problems with using the index, consider the following implementation of copoint:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">using</span> copoint = std::variant&lt; <span class="dt">double</span>, <span class="dt">double</span>, <span class="dt">double</span> &gt;;</code></pre></div>
<p>Use of both <code>std::get&lt;double&gt;</code> and the standard <code>std::visit</code> are impossible due to the repeated <code>double</code> type in the variant. Using the numeric index to work around the issue brings its own problems, however. Consider the following visitor:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">struct</span> visit_f {
  <span class="dt">void</span> <span class="kw">operator</span>()( std::integral_constant&lt;std::size_t, <span class="dv">0</span>&gt;, <span class="dt">double</span> d ) {
    std::cout &lt;&lt; d &lt;&lt; <span class="st">&quot; in x&quot;</span> &lt;&lt; std::endl;
  };
  <span class="dt">void</span> <span class="kw">operator</span>()( std::integral_constant&lt;std::size_t, <span class="dv">1</span>&gt;, <span class="dt">double</span> d ) {
    std::cout &lt;&lt; d &lt;&lt; <span class="st">&quot; in y&quot;</span> &lt;&lt; std::endl;
  };
  <span class="dt">void</span> <span class="kw">operator</span>()( std::integral_constant&lt;std::size_t, <span class="dv">2</span>&gt;, <span class="dt">double</span> d ) {
    std::cout &lt;&lt; d &lt;&lt; <span class="st">&quot; in z&quot;</span> &lt;&lt; std::endl;
  };
};</code></pre></div>
<p>Here we introduce yet another advanced C++ feature, compile-time integrals. In the opinion of the author, this is unfriendly to novices. The problem of duplicated types can be even more insidious, however...</p>
<h3 id="portability-problems">Portability problems</h3>
<p>Consider the following code:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">using</span> json_integral = std::variant&lt; <span class="dt">int</span>, <span class="dt">unsigned</span>, std::size_t, std::ptr_diff_t &gt;;</code></pre></div>
<p>On most platforms, this code will compile and run without a problem. However, if <code>std::size_t</code> happens to be <code>typedef</code>'d to be the same type as <code>unsigned</code> on a particular platform, a compilation error will ensue. The only two options for fixing the error are to fall back to using the index or to make custom wrapper types.</p>
<p>Also notable is that working with third party libraries that are free to change their underlying types creates abstraction leaks when used with a library-based variant.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="co">// Is this code future proof? Not likely. Looks like a foot-gun to me.</span>
<span class="kw">using</span> database_handle = std::variant&lt; ORACLE_HANDLE, BERKELEY_HANDLE &gt;;</code></pre></div>
<p>Because enumerated unions require identifiers as tags, they aren't susceptible to this problem:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">enum</span> <span class="kw">union</span> database_handle {
  ORACLE_HANDLE oracle;
  BERKELEY_HANDLE berkeley;
};</code></pre></div>
<h2 id="syntaxsemantics-overview">Syntax/Semantics Overview</h2>
<p>The definition of an enumerated union would have the same syntax as a <code>union</code>, but with an <code>enum</code> keyword beforehand as in the following example:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="co">// This enumerated union implements a value representing the various commands</span>
<span class="co">// available in a hypothetical shooter game.</span>
<span class="kw">enum</span> <span class="kw">union</span> command {
  std::size_t set_score; <span class="co">// Set the score to the specified value</span>
  std::monotype fire_missile; <span class="co">// Fire a missile</span>
  <span class="dt">unsigned</span> fire_laser; <span class="co">// Fire a laser with the specified intensity</span>
  <span class="dt">double</span> rotate; <span class="co">// Rotate the ship by the specified degrees.</span>
};</code></pre></div>
<p>Each member declaration consists of a type followed by its corresponding identifier.</p>
<h3 id="construction-and-assignment">Construction and Assignment</h3>
<p>A enumerated union has a default constructor if its first member also has a default constructor. A default constructed enumerated union is set to the first member's default constructed value.</p>
<p>Assignment at construction can be used to set the enumerated union to a particular value. The enumerated union is used as a namespace when specifying specific alternatives.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">command cmd = command::set_score( <span class="dv">10</span> );</code></pre></div>
<p>Enumerated union instances can also be assigned to in the course of a program's execution.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">cmd = command::fire_missile( );</code></pre></div>
<p>The behavior of assignment in the presence of exceptions is intentionally left unspecified pending conclusions from the current discussions on a library-based variant.</p>
<h3 id="switch">Switch</h3>
<p>The <code>switch</code> statement on a variant is modeled after that of an <code>enum</code>.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">switch</span>( cmd ) {
  <span class="kw">case</span> set_score value:
    stream &lt;&lt; <span class="st">&quot;Set the score to &quot;</span> &lt;&lt; value &lt;&lt; <span class="st">&quot;.</span><span class="ch">\n</span><span class="st">&quot;</span>;
  <span class="kw">case</span> fire_missile m:
    stream &lt;&lt; <span class="st">&quot;Fire a missile.</span><span class="ch">\n</span><span class="st">&quot;</span>;
  <span class="kw">case</span> fire_laser intensity:
    stream &lt;&lt; <span class="st">&quot;Fire a laser with &quot;</span> &lt;&lt; intensity &lt;&lt; <span class="st">&quot; intensity.</span><span class="ch">\n</span><span class="st">&quot;</span>;
  <span class="kw">case</span> rotate degrees:
    stream &lt;&lt; <span class="st">&quot;Rotate by &quot;</span> &lt;&lt; degrees &lt;&lt; <span class="st">&quot; degrees.</span><span class="ch">\n</span><span class="st">&quot;</span>;
}</code></pre></div>
<p>The notable differences are as follows:</p>
<ol style="list-style-type: decimal">
<li>The <code>case</code> clause includes both the alternative identifier and a variable name that is bound to the alternative's value.</li>
<li>No <code>break</code> statements are necessary since each <code>case</code> statement is independent of the others.</li>
<li>The variable that is bound to the alternative's value has scope until either the next case clause or the end of the switch statement.</li>
</ol>
<p>The <code>default</code> keyword can be used as a catch-all, but it does not have a bound variable.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="co">// Only handle the &#39;set_score&#39; command.</span>
<span class="kw">switch</span>( cmd ) {
  <span class="kw">case</span> set_score value:
    score = value;
  <span class="kw">default</span>:
}</code></pre></div>
<h2 id="design-considerations">Design Considerations</h2>
<h3 id="would-generalized-pattern-matching-solve-all-the-library-based-variant-problems">Would generalized pattern matching solve all the library-based variant problems?</h3>
<p>Although generalized pattern matching as proposed at the November 2014 standardization committee meeting<a href="#fn5" class="footnoteRef" id="fnref5"><sup>5</sup></a> would greatly reduce the syntactic overhead of library-based variants, many problems would still remain. In particular, because types are still being used as tags, users will still need to be quite knowledgeable about advanced C++ topics to use them effectively.</p>
<h3 id="how-does-the-proposed-pattern-matching-compare-with-generalized-pattern-matching">How does the proposed pattern matching compare with generalized pattern matching?</h3>
<p>Because there has not been a concrete generalized pattern matching proposal as of yet, it is difficult to make direct comparisons. The design of pattern matching in this proposal has been made <em>intentionally simple</em> to ease the burden on compiler implementers and moderate complexity for new users.</p>
<p>On the flip-side, the particular syntax chosen here was also designed to be easily extended to handle more complex pattern matching variations in future revisions of the language. For example:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">enum</span> <span class="kw">union</span> position_command {
  <span class="dt">double</span> set_rotation;
  std::pair&lt; <span class="dt">double</span>, <span class="dt">double</span> &gt; set_position;
};

<span class="dt">void</span> f( position_command cmd ) {
  <span class="kw">switch</span>( cmd ) {
    <span class="kw">case</span> set_rotation r:
      <span class="co">// ...</span>
    <span class="kw">case</span> set_position {<span class="fl">0.</span><span class="dv">0</span>, <span class="fl">0.</span><span class="dv">0</span>}:
      <span class="co">// handle the origin case specially</span>
      <span class="co">// ...</span>
    <span class="kw">case</span> set_position {x, y}:
      <span class="co">// handle other cases</span>
      <span class="co">// ...</span>
  }
}</code></pre></div>
<h2 id="conclusion">Conclusion</h2>
<p>We conclude that types-as-tags are for astronauts, but variants are for everyone. None of the library implementations thus far proposed are easy enough to be used by beginners; a language feature is necessary. In the author's opinion a library-based variant should complement a language-based variant, but not replace it.</p>
<div class="footnotes">
<hr />
<ol>
<li id="fn1"><p>Variant: a type-safe union (v4). N4542<a href="#fnref1">↩</a></p></li>
<li id="fn2"><p>The <code>std::monotype</code> type, which has only one value, is from variant proposal N4542.<a href="#fnref2">↩</a></p></li>
<li id="fn3"><p>See <a href="https://github.com/isocpp/CppCoreGuidelines">The C++ Core Guidelines</a> rule C.2.<a href="#fnref3">↩</a></p></li>
<li id="fn4"><p>Compare that code to the same for an enumerated union:</p>
<pre><code>enum union double_or_string {
  double with_double;
  std::string with_string;
};

void f( double_or_string v ) {
  switch( v ) {
    case with_double d:
      std::cout &lt;&lt; &quot;Got a double &quot; &lt;&lt; d &lt;&lt; std::endl;
    case with_string s:
      std::cout &lt;&lt; &quot;Got a string &quot; &lt;&lt; s &lt;&lt; std::endl;
  }
}</code></pre>
<a href="#fnref4">↩</a></li>
<li id="fn5"><p>Pattern Matching for C++. Yuriy Solodkyy, Gabriel Dos Reis, and Bjarne Stroustrup.<a href="#fnref5">↩</a></p></li>
</ol>
</div>
</body>
</html>
