<!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="pattern-matching-and-language-variants">Pattern Matching and Language Variants</h1>
<ul>
<li>Document number: P0095R1</li>
<li>Date: 2016-05-29</li>
<li>Reply-to: David Sankel &lt;david@stellarscience.com&gt;</li>
<li>Audience: Evolution</li>
</ul>
<h2 id="abstract">Abstract</h2>
<p>Pattern matching and language-based variants improve code readability, make the language easier to use, and prevent common mishaps. This paper proposes a syntax that extends C++ to provide these two commonly requested features.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">lvariant json_value {
  std::map&lt; std::string, json_value &gt; object;
  std::vector&lt; json_value &gt; array;
  std::string string;
  <span class="dt">double</span> number;
  <span class="dt">bool</span> boolean;
  std::monostate nullary;
};</code></pre></div>
<h2 id="history">History</h2>
<p><em>P0095R1</em>. Merged in blog post developments. Added <code>nullptr</code> patterns, <code>@</code> patterns, and pattern guards. A mechanism for dealing with assignment was also added. Wording as it relates to patterns was added. Made expression and statement <code>inspect</code>s use a single keyword.</p>
<p><em>C++ Langauge Support for Pattern Matching and Variants</em> blog post. Sketched out several ideas on how a more extensive pattern matching feature would look. Discussed an extension mechanism which would allow any type to act tuple-like or variant-like. <code>lvariant</code> is used instead of <code>enum union</code> based on feedback in Kona.</p>
<p><em>Kona 2015 Meeting</em>. There was discussion on whether or not a partial pattern-matching solution would be sufficient for incorporation of a language-based variant. While exploration of a partial solution had consensus at 5-12-8-2-0, exploration of a full solution had a strong consensus at 16-6-5-1-0. The question was also asked whether or not we want a language-based variant and the result was 2-19-6-0-1.</p>
<p><em>P0095R0</em>. The initial version of this paper presented in Kona. It motivated the need for a language-based variant and sketched a basic design for such a feature with the minimal pattern matching required.</p>
<h2 id="beforeafter-comparisons">Before/After Comparisons</h2>
<figure>
<figcaption>
Figure 1. Declaration of a command data structure.
</figcaption>
<table border="1">
<tr>
<th>
before
</th>
<th>
after
</th>
</tr>
<tr>
<td valign="top">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">struct</span> set_score {
  std::size_t value;
};

<span class="kw">struct</span> fire_missile {};

<span class="kw">struct</span> fire_laser {
  <span class="dt">unsigned</span> intensity;
};

<span class="kw">struct</span> rotate {
  <span class="dt">double</span> amount;
};

<span class="kw">struct</span> command {
  std::variant&lt;
    set_score,
    fire_missile,
    fire_laser,
    rotate &gt; value;
};</code></pre></div>
</td>
<td valign="top">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">lvariant command {
  std::size_t set_score;
  std::monostate fire_missile;
  <span class="dt">unsigned</span> fire_laser;
  <span class="dt">double</span> rotate;
};</code></pre></div>
</td>
</tr>
</table>
</figure>
<figure>
<figcaption>
Figure 2: Implementation of an output operator
</figcaption>
<table border="1">
<tr>
<th>
before
</th>
<th>
after
</th>
</tr>
<tr>
<td valign="top">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">namespace</span> {
<span class="kw">struct</span> Output {
  std::ostream&amp; <span class="kw">operator</span>()(std::ostream&amp; stream, <span class="dt">const</span> set_score&amp; ss) <span class="dt">const</span> {
    <span class="kw">return</span> stream &lt;&lt; <span class="st">&quot;Set the score to &quot;</span> &lt;&lt; ss.value &lt;&lt; <span class="st">&quot;.</span><span class="ch">\n</span><span class="st">&quot;</span>;
  }
  std::ostream&amp; <span class="kw">operator</span>()(std::ostream&amp; stream, <span class="dt">const</span> fire_missile&amp;) <span class="dt">const</span> {
    <span class="kw">return</span> stream &lt;&lt; <span class="st">&quot;Fire a missile.</span><span class="ch">\n</span><span class="st">&quot;</span>;
  }
  std::ostream&amp; <span class="kw">operator</span>()(std::ostream&amp; stream, <span class="dt">const</span> fire_laser&amp; fl) <span class="dt">const</span> {
    <span class="kw">return</span> stream &lt;&lt; <span class="st">&quot;Fire a laser with &quot;</span> &lt;&lt; fl.intensity &lt;&lt; <span class="st">&quot; intensity.</span><span class="ch">\n</span><span class="st">&quot;</span>;
  }
  std::ostream&amp; <span class="kw">operator</span>()(std::ostream&amp; stream, <span class="dt">const</span> rotate&amp; r) <span class="dt">const</span> {
    <span class="kw">return</span> stream &lt;&lt; <span class="st">&quot;Rotate by &quot;</span> &lt;&lt; r.degrees &lt;&lt; <span class="st">&quot; degrees.</span><span class="ch">\n</span><span class="st">&quot;</span>
  }
};
}

std::ostream&amp; <span class="kw">operator</span>&lt;&lt;(std::ostream&amp; stream, <span class="dt">const</span> command&amp; cmd) {
  <span class="kw">return</span> std::visit(std::bind(Output(), std::ref(stream), std::placeholders::_1),
                    cmd.value);
}</code></pre></div>
</td>
<td valign="top">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">std::ostream&amp; <span class="kw">operator</span>&lt;&lt;(std::ostream&amp; stream, <span class="dt">const</span> command&amp; cmd) {
  <span class="kw">return</span> inspect(cmd) {
    set_score value =&gt;
      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>
    fire_missile _ =&gt;
      stream &lt;&lt; <span class="st">&quot;Fire a missile.</span><span class="ch">\n</span><span class="st">&quot;</span>
    fire_laser intensity =&gt;
      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>
    rotate degrees =&gt;
      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>
</td>
</tr>
</table>
</figure>
<figure>
<figcaption>
Figure 3: Switching an enum.
</figcaption>
<table border="1">
<tr>
<th>
before
</th>
<th>
after
</th>
</tr>
<tr>
<td colspan="2">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">enum</span> color { red, yellow, green, blue };</code></pre></div>
</td>
</tr>
<td valign="top">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">const</span> Vec3 opengl_color = [&amp;c] {
  <span class="kw">switch</span>(c) {
    <span class="kw">case</span> red:
      <span class="kw">return</span> Vec3(<span class="fl">1.0</span>, <span class="fl">0.0</span>, <span class="fl">0.0</span>);
      <span class="kw">break</span>;
    <span class="kw">case</span> yellow:
      <span class="kw">return</span> Vec3(<span class="fl">1.0</span>, <span class="fl">1.0</span>, <span class="fl">0.0</span>);
      <span class="kw">break</span>;
    <span class="kw">case</span> green:
      <span class="kw">return</span> Vec3(<span class="fl">0.0</span>, <span class="fl">1.0</span>, <span class="fl">0.0</span>);
      <span class="kw">break</span>;
    <span class="kw">case</span> blue:
      <span class="kw">return</span> Vec3(<span class="fl">0.0</span>, <span class="fl">0.0</span>, <span class="fl">1.0</span>);
      <span class="kw">break</span>;
    <span class="kw">default</span>:
      std::abort();
  }();</code></pre></div>
</td>
<td valign="top">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">const</span> Vec3 opengl_color =
  inspect(c) {
    red    =&gt; Vec3(<span class="fl">1.0</span>, <span class="fl">0.0</span>, <span class="fl">0.0</span>)
    yellow =&gt; Vec3(<span class="fl">1.0</span>, <span class="fl">1.0</span>, <span class="fl">0.0</span>)
    green  =&gt; Vec3(<span class="fl">0.0</span>, <span class="fl">1.0</span>, <span class="fl">0.0</span>)
    blue   =&gt; Vec3(<span class="fl">0.0</span>, <span class="fl">0.0</span>, <span class="fl">1.0</span>)
  };</code></pre></div>
</td>
</tr>
</table>
</figure>
<figure>
<figcaption>
Figure 4: Expression Datatype
</figcaption>
<table border="1">
<tr>
<th>
before
</th>
<th>
after
</th>
</tr>
<td valign="top">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">struct</span> expression;
 
<span class="kw">struct</span> sum_expression {
  std::unique_ptr&lt;expression&gt; left_hand_side;
  std::unique_ptr&lt;expression&gt; right_hand_side;
};
 
<span class="kw">struct</span> expression {
  std::variant&lt;sum_expression, <span class="dt">int</span>, std::string&gt; value;
};

expression simplify(<span class="dt">const</span> expression &amp; exp) {
  <span class="kw">if</span>(sum_expression <span class="dt">const</span> * <span class="dt">const</span> sum = std::get_if&lt;sum_expression&gt;(&amp;exp)) {
    <span class="kw">if</span>( <span class="dt">int</span> <span class="dt">const</span> * <span class="dt">const</span> lhsInt = std::get_if&lt;<span class="dt">int</span>&gt;( sum-&gt;left_hand_side.get() )
      &amp;&amp; *lhsInt == <span class="dv">0</span> ) {
      <span class="kw">return</span> simplify(*sum-&gt;right_hand_side);
    }
    <span class="kw">else</span> <span class="kw">if</span>( <span class="dt">int</span> <span class="dt">const</span> * <span class="dt">const</span> rhsInt = std::get_if&lt;<span class="dt">int</span>&gt;( sum-&gt;right_hand_side.get() )
            &amp;&amp; *rhsInt == <span class="dv">0</span> ) {
      <span class="kw">return</span> simplify(*sum-&gt;left_hand_side);
    } <span class="kw">else</span> {
      <span class="kw">return</span> {sum_expression{
        std::make_unique&lt;expression&gt;(simplify(*sum-&gt;left_hand_side)),
        std::make_unique&lt;expression&gt;(simplify(*sum-&gt;right_hand_side))}}
    }
  }
  <span class="kw">return</span> exp;
}

<span class="dt">void</span> simplify2(expression &amp; exp) {
  <span class="kw">if</span>(sum_expression * <span class="dt">const</span> sum = std::get_if&lt;sum_expression&gt;(&amp;exp)) {
    <span class="kw">if</span>( <span class="dt">int</span> * <span class="dt">const</span> lhsInt = std::get_if&lt;<span class="dt">int</span>&gt;( sum-&gt;left_hand_side.get() )
      &amp;&amp; *lhsInt == <span class="dv">0</span> ) {
      expression tmp(std::move(*sum-&gt;right_hand_side));
      exp = std::move(tmp);
      simplify(exp);
    }
    <span class="kw">else</span> <span class="kw">if</span>( <span class="dt">int</span> * <span class="dt">const</span> rhsInt = std::get_if&lt;<span class="dt">int</span>&gt;( sum-&gt;right_hand_side.get() )
            &amp;&amp; *rhsInt == <span class="dv">0</span> ) {
      expression tmp(std::move(*sum-&gt;left_hand_side));
      exp = std::move(tmp);
      simplify(exp);
    } <span class="kw">else</span> {
      simplify(*sum-&gt;left_hand_side);
      simplify(*sum-&gt;right_hand_side);
    }
  }
  <span class="kw">return</span> exp;
}</code></pre></div>
</td>
<td valign="top">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">lvariant expression;
 
<span class="kw">struct</span> sum_expression {
  std::unique_ptr&lt;expression&gt; left_hand_side;
  std::unique_ptr&lt;expression&gt; right_hand_side;
};
 
lvariant expression {
  sum_expression sum;
  <span class="dt">int</span> literal;
  std::string var;
};

expression simplify(<span class="dt">const</span> expression &amp; exp) {
  <span class="kw">return</span> inspect(exp) {
           sum {*(literal <span class="dv">0</span>),         *rhs} =&gt; simplify(rhs)
           sum {*lhs        , *(literal <span class="dv">0</span>)} =&gt; simplify(lhs)
           sum {*lhs        ,         *rhs}
             =&gt; expression::sum{
                  std::make_unique&lt;expression&gt;(simplify(lhs)),
                  std::make_unique&lt;expression&gt;(simplify(rhs))};
           _ =&gt; exp
         };
}

<span class="dt">void</span> simplify2(expression &amp; exp) {
  inspect(exp) {
     sum {*(literal <span class="dv">0</span>),         *rhs} =&gt; {
       expression tmp(std::move(rhs));
       exp = std::move(tmp);
       simplify2(exp);
     }
     sum {*lhs        , *(literal <span class="dv">0</span>)} =&gt; {
       expression tmp(std::move(lhs));
       exp = std::move(tmp);
       simplify2(exp);
     }
     sum {*lhs        ,         *rhs} =&gt; {
       simplify2(lhs);
       simplify2(rhs);
     }
     _ =&gt; ;
   };
}</code></pre></div>
</td>
</tr>
</table>
</figure>
<figure>
<figcaption>
Figure 4: <code>struct</code> inspection
</figcaption>
<table border="1">
<tr>
<th>
before
</th>
<th>
after
</th>
</tr>
<tr>
<td colspan="2">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">struct</span> player {
  std::string name;
  <span class="dt">int</span> hitpoints;
  <span class="dt">int</span> lives;
};</code></pre></div>
</td>
</tr>
<td valign="top">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">void</span> takeDamage(player &amp;p) {
  <span class="kw">if</span>(p.hitpoints == <span class="dv">0</span> &amp;&amp; p.lives == <span class="dv">0</span>)
    gameOver();
  <span class="kw">else</span> <span class="kw">if</span>(p.hitpoints == <span class="dv">0</span>) {
    p.hitpoints = <span class="dv">10</span>;
    p.lives--;
  }
  <span class="kw">else</span> <span class="kw">if</span>(p.hitpoints &lt;= <span class="dv">3</span>) {
    p.hitpoints--;
    messageAlmostDead();
  }
  <span class="kw">else</span> {
    p.hitpoints--;
  }
}</code></pre></div>
</td>
<td valign="top">
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">void</span> takeDamage(player &amp;p) {
  inspect(p) {
    {hitpoints:   <span class="dv">0</span>, lives:<span class="dv">0</span>}   =&gt; gameOver();
    {hitpoints:hp<span class="er">@</span><span class="dv">0</span>, lives:l}   =&gt; hp=<span class="dv">10</span>, l--;
    {hitpoints:hp} <span class="kw">if</span> (hp &lt;= <span class="dv">3</span>) =&gt; { hp--; messageAlmostDead(); }
    {hitpoints:hp} =&gt; hp--;
  }
}</code></pre></div>
</td>
</tr>
</table>
</figure>
<h2 id="introduction">Introduction</h2>
<p>There is general agreement that language-based variants and pattern matching would make C++ programmers more productive. However, a design that has the elegance of a functional language, but with the performance and utility of a systems language is not forthcoming. Add to that the requirements of backwards compatibility and consistency with the rest of C++, and we've got quite a challenging problem.</p>
<p>This paper presents a design for language variants and pattern matching that the authors feel has the right mix of syntactic elegance, low-level performance, and consistency with other language features.</p>
<p>The following snippet illustrates our proposed syntax.<a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a></p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="co">// This lvariant implements a value representing the various commands</span>
<span class="co">// available in a hypothetical shooter game.</span>
lvariant command {
  std::size_t set_score; <span class="co">// Set the score to the specified value</span>
  std::monostate 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">return</span> inspect( cmd ) {
    set_score value =&gt;
      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>
    fire_missile m =&gt;
      stream &lt;&lt; <span class="st">&quot;Fire a missile.</span><span class="ch">\n</span><span class="st">&quot;</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>
    rotate degrees =&gt;
      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>
<p>The current library-based variant proposal solves an important need<a href="#fn2" class="footnoteRef" id="fnref2"><sup>2</sup></a>, but they are too complicated for novice users. We describe difficult corner cases, the pitfalls of using types as tags, and the difficulty of writing portable code using a library based variant. All of these problems suggest the necessity of a language-based variant feature in C++.</p>
<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">lvariant 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">lvariant database_handle {
  ORACLE_HANDLE oracle;
  BERKELEY_HANDLE berkeley;
};</code></pre></div>
<h2 id="language-based-variant-lvariant">Language Based Variant <code>lvariant</code></h2>
<p>The definition of an lvariant has the same syntax as a <code>union</code>, but with an <code>lvariant</code> keyword as in the following example:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="co">// This lvariant implements a value representing the various commands</span>
<span class="co">// available in a hypothetical shooter game.</span>
lvariant command {
  std::size_t set_score; <span class="co">// Set the score to the specified value</span>
  std::monostate 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>An lvariant has a default constructor if its first field also has a default constructor. A default constructed lvariant is set to the first fields's default constructed value.</p>
<p>Assignment at construction can be used to set the lvariant to a particular value. The lvariant 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>lvariant instances can also be assigned 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>
<h3 id="inspection">Inspection</h3>
<p>Extracting values from an lvariant is acomplished with a new <code>inspect</code> keyword. Much more will be said about this keyword in the pattern matching section of this paper.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">inspect( cmd ) {
  set_score value =&gt;
    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>;
  fire_missile m =&gt;
    stream &lt;&lt; <span class="st">&quot;Fire a missile.</span><span class="ch">\n</span><span class="st">&quot;</span>;
  fire_laser intensity =&gt;
    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>;
  rotate degrees =&gt;
    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>
<h3 id="assignment">Assignment</h3>
<p>As with library-based variants, the behavior of assignment when an exception is thrown is of considerable concern. We propose the following for lvariants:</p>
<ul>
<li>If any of the alternatives is not friendly (ie. has a possibly throwing move constructor or a possibly throwing move assignment operator), there will not be a default assignment operator for the lvariant.</li>
<li>Users will have the ability to implement their own assignment operator to their liking.</li>
</ul>
<p>This provides a safe default and supports users of differing philosophies.</p>
<p>The &quot;I'm broken. You deal with it.&quot; philosophy allows the <code>lvariant</code> to get into a state where the only valid operations are assignment and destruction. This is accomplished by overriding the assignment operator and allowing the 'std::valueless_by_exception' exception to pass through to callers.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">lvariant Foo {
  PossiblyThrowingMoveAssignmentType field1;
  std::string field2;

  <span class="co">// Possibly throw a &#39;std::valueless_by_exception&#39; exception which makes this</span>
  <span class="co">// object only assignable and destructable.</span>
  Foo&amp; <span class="kw">operator</span>=(<span class="dt">const</span> Foo&amp; rhs);
  Foo&amp; <span class="kw">operator</span>=(<span class="dt">const</span> Foo&amp;&amp; rhs); <span class="co">// implementation skipped</span>
};

Foo&amp; Foo::<span class="kw">operator</span>=(<span class="dt">const</span> Foo&amp; rhs)
{
  <span class="co">// This can possibly throw a &#39;std::valueless_by_exception&#39; exception.</span>
  lvariant(*<span class="kw">this</span>) = rhs;
}</code></pre></div>
<p>The &quot;exception are for sissies&quot; philosophy essentially terminates the program if there's an exception on assignment. This is accomplished by marking the assignment operator <code>noexcept</code>.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">lvariant Foo {
  PossiblyThrowingMoveAssignmentType field1;
  std::string field2;

  Foo&amp; <span class="kw">operator</span>=(<span class="dt">const</span> Foo&amp; rhs) <span class="kw">noexcept</span>;
  Foo&amp; <span class="kw">operator</span>=(<span class="dt">const</span> Foo&amp;&amp; rhs) <span class="kw">noexcept</span>; <span class="co">// implementation skipped</span>
};

Foo&amp; <span class="kw">operator</span>=(<span class="dt">const</span> Foo&amp; rhs) <span class="kw">noexcept</span>
{
  lvariant(*<span class="kw">this</span>) = rhs;
}</code></pre></div>
<p>The &quot;embrace emptiness&quot; philosophy switches to a special empty state if there's an exception on assignment. This is accomplished by handling the <code>std::valueless_by_exception</code> exception within the assignment operator.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">lvariant Foo {
  PossiblyThrowingMoveAssignmentType field1;
  std::string field2;
  std::monostate empty;

  Foo&amp; <span class="kw">operator</span>=(<span class="dt">const</span> Foo&amp; rhs);
  Foo&amp; <span class="kw">operator</span>=(<span class="dt">const</span> Foo&amp;&amp; rhs); <span class="co">// implementation skipped</span>
};

Foo&amp; <span class="kw">operator</span>=(<span class="dt">const</span> Foo&amp; rhs)
{
  <span class="kw">try</span> {
    lvariant(*<span class="kw">this</span>) = rhs;
  }
  <span class="kw">catch</span>(std::valueless_by_exception&amp;) {
    lvariant(*<span class="kw">this</span>) = Foo::empty();
  }
}</code></pre></div>
<h2 id="pattern-matching-with-inspect">Pattern Matching With <code>inspect</code></h2>
<p>Pattern matching goes far beyond <code>lvariant</code>s. This section overviews the proposed pattern matching syntax and how it applies to all types.</p>
<p>Lets define some useful terms for discussing pattern matching and variants in C++. We use the word &quot;piece&quot; to denote a field in a <code>struct</code>. The word &quot;alternative&quot; is used for <code>lvariant</code> fields. The programming language theory savvy will also recognize <code>lvariant</code>s to be <a href="https://en.wikipedia.org/wiki/Tagged_union">sum types</a> and simple <code>struct</code>s to be <a href="https://en.wikipedia.org/wiki/Product_type">product types</a>, although we won't use that jargon here.</p>
<h3 id="pattern-matching-integrals-and-enums">Pattern matching integrals and enums</h3>
<p>The most basic pattern matching is that of integral (ie. <code>int</code>, <code>long</code>, <code>char</code>, etc.) and <code>enum</code> types, and that is the subject of this section. Before we get there, however, we need to distinguish between the two places pattern matching can occur. The first is in the statement context. This context is most useful when the intent of the pattern is to produce some kind of action. The <code>if</code> statement, for example, is used in this way. The second place pattern matching can occur is is in an expression context. Here the intent of the pattern is to produce a value of some sort. The trinary operator <code>?:</code>, for example, is used in this context. Upcoming examples will help clarify the distinction.</p>
<p>The context is distinguished by whether or not the cases consist of a statement (ends in a semicolon or is wrapped in curly braces) or an expression.</p>
<p>In the following example, we're using <code>inspect</code> as a statement to check for certain values of an int <code>i</code>:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">inspect(i) {
  <span class="dv">0</span> =&gt;
    std::cout &lt;&lt; <span class="st">&quot;I can&#39;t say I&#39;m positive or negative on this syntax.&quot;</span>
              &lt;&lt; std::endl;
  <span class="dv">6</span> =&gt;
    std::cout &lt;&lt; <span class="st">&quot;Perfect!&quot;</span> &lt;&lt; std::endl;
  _ =&gt;
    std::cout &lt;&lt; <span class="st">&quot;I don&#39;t know what to do with this.&quot;</span> &lt;&lt; std::endl;
}</code></pre></div>
<p>The <code>_</code> character is the pattern which always succeeds. It represents a wildcard or fallthrough. The above code is equivalent to the following <code>switch</code> statement.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">switch</span>(i) {
  <span class="kw">case</span> <span class="dv">0</span>:
    std::cout &lt;&lt; <span class="st">&quot;I can&#39;t say I&#39;m positive or negative on this syntax.&quot;</span>
              &lt;&lt; std::endl;
    <span class="kw">break</span>;
  <span class="kw">case</span> <span class="dv">6</span>:
    std::cout &lt;&lt; <span class="st">&quot;Perfect!&quot;</span> &lt;&lt; std::endl;
    <span class="kw">break</span>;
  <span class="kw">default</span>:
    std::cout &lt;&lt; <span class="st">&quot;I don&#39;t know what to do with this.&quot;</span> &lt;&lt; std::endl;
}</code></pre></div>
<p><code>inspect</code> can be used to pattern match within expression contexts as in the following example. <code>c</code> is an instance of the <code>color</code> <code>enum</code>:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">enum</span> color { red, yellow, green, blue };

<span class="co">// elsewhere...</span>

<span class="dt">const</span> Vec3 opengl_color = inspect(c) {
                            red    =&gt; Vec3(<span class="fl">1.0</span>, <span class="fl">0.0</span>, <span class="fl">0.0</span>)
                            yellow =&gt; Vec3(<span class="fl">1.0</span>, <span class="fl">1.0</span>, <span class="fl">0.0</span>)
                            green  =&gt; Vec3(<span class="fl">0.0</span>, <span class="fl">1.0</span>, <span class="fl">0.0</span>)
                            blue   =&gt; Vec3(<span class="fl">0.0</span>, <span class="fl">0.0</span>, <span class="fl">1.0</span>)
                          };</code></pre></div>
<p>Note that the cases do not end in a semicolon.</p>
<p>It is also important to note that if an <code>inspect</code> expression does not have a matching pattern, an <code>std::no_match</code> exception is thrown. This differs from <code>inspect</code> statements which simply move on to the next statement if no pattern matches.</p>
<p>All we've seen so far is a condensed and safer <code>switch</code> syntax which can also be used in expressions. Pattern matching's real power comes when we use more complex patterns. We'll see some of that below.</p>
<h3 id="pattern-matching-structs">Pattern matching structs</h3>
<p>Pattern matching <code>struct</code>s in isolation isn't all that interesting: they merely bind new identifiers to each of the fields.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">struct</span> player {
  std::string name;
  <span class="dt">int</span> hitpoints;
  <span class="dt">int</span> coins;
};</code></pre></div>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">void</span> log_player( <span class="dt">const</span> player &amp; p ) {
  inspect(p) {
    {n,h,c}
      =&gt; std::cout &lt;&lt; n &lt;&lt; <span class="st">&quot; has &quot;</span> &lt;&lt; h &lt;&lt; <span class="st">&quot; hitpoints and &quot;</span> &lt;&lt; c &lt;&lt; <span class="st">&quot; coins.&quot;</span>;
  }
}</code></pre></div>
<p><code>n</code>, <code>h</code>, and <code>c</code> are &quot;bound&quot; to their underlying values in a similar way to structured bindings. See <a href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0217r1.html">P0217R1</a> for more information on what it means to bind a value.</p>
<p><code>struct</code> patterns aren't limited to binding new identifiers though. We can instead use a nested pattern as in the following example.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">void</span> get_hint( <span class="dt">const</span> player &amp; p ) {
  inspect( p ) {
    {_, <span class="dv">1</span>, _} =&gt; std::cout &lt;&lt; <span class="st">&quot;You&#39;re almost destroyed. Give up!&quot;</span> &lt;&lt; std::endl;
    {_,<span class="dv">10</span>,<span class="dv">10</span>} =&gt; std::cout &lt;&lt; <span class="st">&quot;I need the hints from you!&quot;</span> &lt;&lt; std::endl;
    {_, _,<span class="dv">10</span>} =&gt; std::cout &lt;&lt; <span class="st">&quot;Get more hitpoints!&quot;</span> &lt;&lt; std::endl;
    {_,<span class="dv">10</span>, _} =&gt; std::cout &lt;&lt; <span class="st">&quot;Get more ammo!&quot;</span> &lt;&lt; std::endl;
    {n, _, _} =&gt; <span class="kw">if</span>( n != <span class="st">&quot;The Bruce Dickenson&quot;</span> )
                   std::cout &lt;&lt; <span class="st">&quot;Get more hitpoints and ammo!&quot;</span> &lt;&lt; std::endl;
                 <span class="kw">else</span>
                   std::cout &lt;&lt; <span class="st">&quot;More cowbell!&quot;</span> &lt;&lt; std::endl;
  }
}</code></pre></div>
<p>While the above code is certainly condensed, it lacks clarity. It is tedious to remember the ordering of a <code>struct</code>'s fields. Not all is lost, though; Alternatively we can match using field names.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">void</span> get_hint( <span class="dt">const</span> player &amp; p ) {
  inspect(p) {

    {hitpoints:<span class="dv">1</span>}
      =&gt; std::cout &lt;&lt; <span class="st">&quot;You&#39;re almost destroyed. Give up!&quot;</span> &lt;&lt; std::endl;

    {hitpoints:<span class="dv">10</span>, coins:<span class="dv">10</span>}
      =&gt; std::cout &lt;&lt; <span class="st">&quot;I need the hints from you!&quot;</span> &lt;&lt; std::endl;

    {coins:<span class="dv">10</span>}
      =&gt; std::cout &lt;&lt; <span class="st">&quot;Get more hitpoints!&quot;</span> &lt;&lt; std::endl;

    {hitpoints:<span class="dv">10</span>}
      =&gt; std::cout &lt;&lt; <span class="st">&quot;Get more ammo!&quot;</span> &lt;&lt; std::endl;

    {name:n}
      =&gt; <span class="kw">if</span>( n != <span class="st">&quot;The Bruce Dickenson&quot;</span> )
           std::cout &lt;&lt; <span class="st">&quot;Get more hitpoints and ammo!&quot;</span> &lt;&lt; std::endl;
         <span class="kw">else</span>
           std::cout &lt;&lt; <span class="st">&quot;More cowbell!&quot;</span> &lt;&lt; std::endl;
  }
}</code></pre></div>
<p>Finally, our patterns can incorporate guards through use if an if clause. The last pattern in the above function can be replaced with the following two patterns:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">{name:n} <span class="kw">if</span>( n == <span class="st">&quot;The Bruce Dickenson&quot;</span> ) =&gt; std::cout &lt;&lt; <span class="st">&quot;More cowbell!&quot;</span> &lt;&lt; std::endl;
_ =&gt; std::cout &lt;&lt; <span class="st">&quot;Get more hitpoints and ammo!&quot;</span> &lt;&lt; std::endl;</code></pre></div>
<h3 id="pattern-matching-lvariants">Pattern matching <code>lvariant</code>s</h3>
<p>Pattern matching is the easiest way to work with <code>lvariant</code>s. Consider the following binary tree with <code>int</code> leaves.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">lvariant tree {
  <span class="dt">int</span> leaf;
  std::pair&lt; std::unique_ptr&lt;tree&gt;, std::unique_ptr&lt;tree&gt; &gt; branch;
}</code></pre></div>
<p>Say we need to write a function which returns the sum of a <code>tree</code> object's leaf values. Variant patterns are just what we need. A pattern which matches an alternative consists of the alternative's name followed by a pattern for its associated value.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">int</span> sum_of_leaves( <span class="dt">const</span> tree &amp; t ) {
  <span class="kw">return</span> inspect( t ) {
           leaf i =&gt; i
           branch b =&gt; sum_of_leaves(*b.first) + sum_of_leaves(*b.second)
         };
}</code></pre></div>
<p>Assuming we can pattern match on the <code>std::pair</code> type, which we'll discuss later, this could be rewritten as follows.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">int</span> sum_of_leaves( <span class="dt">const</span> tree &amp; t ) {
  <span class="kw">return</span> inspect( t ) {
           leaf i =&gt; i
           branch {left, right} =&gt; sum_of_leaves(*left) + sum_of_leaves(*right)
         };
}</code></pre></div>
<h3 id="more-complex-datatypes">More complex datatypes</h3>
<p>Pattern matching can make difficult code more readable and maintainable. This is especially true with complex patterns. Consider the following arithmetic expression datatype:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="co">// An lvariant (forward) declaration.</span>
lvariant expression;

<span class="kw">struct</span> sum_expression {
  std::unique_ptr&lt;expression&gt; left_hand_side;
  std::unique_ptr&lt;expression&gt; right_hand_side;
};

lvariant expression {
  sum_expression sum;
  <span class="dt">int</span> literal;
  std::string var;
};</code></pre></div>
<p>We'd like to write a function which simplifies expressions by exploiting <code>exp + 0 = 0</code> and <code>0 + exp = 0</code> identities. Here is how that function can be written with pattern matching.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="co">// The behavior is undefined unless `exp` has no null pointers.</span>
expression simplify( <span class="dt">const</span> expression &amp; exp ) {
  <span class="kw">return</span> inspect( exp ) {
           sum {*(literal <span class="dv">0</span>),         *rhs} =&gt; simplify(rhs)
           sum {*lhs        , *(literal <span class="dv">0</span>)} =&gt; simplify(lhs)
           _ =&gt; exp
         };
}</code></pre></div>
<p>Here we've introduced a new <code>*</code> keyword into our patterns. <code>*&lt;pattern&gt;</code> matches against types which have a valid dereferencing operator and uses <code>&lt;pattern&gt;</code> on the value pointed to (as opposed to matching on the pointer itself). A special dereferencing pattern syntax may seem strange for folks coming from a functional language. However, when we take into account that C++ uses pointers for all recursive structures it makes a lot of sense. Without it, the above pattern would be much more complicated.</p>
<h2 id="opting-into-pattern-matching-with-custom-types">Opting into Pattern Matching with Custom Types</h2>
<h3 id="pattern-matching-tuple-like-types">Pattern matching tuple-like types</h3>
<p>Now we have patterns for integrals, <code>enum</code>s, simple <code>struct</code>s, and <code>lvariant</code>s. Is there a way to enable pattern matching for custom data types? The answer, of course, is yes.</p>
<p>Tuple-like types are those which behave a lot like simple <code>struct</code>s. These objects represent a sequence of values of various types. <code>std::pair</code> and <code>std::tuple</code> are notable examples. In this section we'll see how we can annotate custom tuple types for pattern matching.</p>
<p>Pattern matching for tuple-like types is accomplished by overloading the <code>extract</code> operator. Imagine we have a custom <code>pair</code> type that has its <code>m_first</code> and <code>m_second</code> member variables declared private. We overload the <code>extract</code> operator as follows:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;<span class="kw">class</span> T1, <span class="kw">class</span> T2&gt;
<span class="kw">class</span> pair {
  T1 m_first;
  T2 m_second;

<span class="kw">public</span>:
  <span class="co">// etc.</span>

  <span class="kw">operator</span> extract( std::tuple_piece&lt;T1&gt; x, std::tuple_piece&lt;T2&gt; y ) {
    x.set( &amp;<span class="kw">this</span>-&gt;first );
    y.set( &amp;<span class="kw">this</span>-&gt;second );
  }
};</code></pre></div>
<p>The signature of the extract operator function provides both the number of pieces and the type of each piece. The code in the body of this operator overload connects the actual pieces <code>m_first</code> and <code>m_second</code> to their placeholders <code>x</code> and <code>y</code>. This is all that is required for the compiler to use tuple-like objects in pattern matching.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">inspect(pair&lt;<span class="dt">int</span>,std::string&gt;(<span class="dv">3</span>, <span class="st">&quot;Hello World&quot;</span>)) {
  {<span class="dv">3</span>, s} =&gt; std::cout &lt;&lt; <span class="st">&quot;Three, a special number, says &quot;</span> &lt;&lt; s &lt;&lt; std::endl;
  {i, s} =&gt; std::cout &lt;&lt; i &lt;&lt; <span class="st">&quot;, a boring number, says &quot;</span> &lt;&lt; s &lt;&lt; std::endl;
}</code></pre></div>
<p>It is also possible to incorporate named labels. We could do this by setting the second template parameter of the <code>std::tuple_piece</code> type:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;<span class="kw">class</span> T1, <span class="kw">class</span> T2&gt;
<span class="kw">struct</span> pair {
  <span class="kw">enum</span> field_name { first, second };

  <span class="kw">operator</span> extract( std::tuple_piece&lt;T1, first&gt; x, std::tuple_piece&lt;T2, second&gt; y ) {
    x.set( &amp;<span class="kw">this</span>-&gt;m_first );
    y.set( &amp;<span class="kw">this</span>-&gt;m_second );
  }
<span class="kw">private</span>:
  T1 m_first;
  T2 m_second;
};</code></pre></div>
<p>Then we could do:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">inspect(pair&lt;<span class="dt">double</span>,<span class="dt">int</span>&gt;(<span class="fl">1.0</span>, <span class="dv">3</span>)) {
  {first:d, second:<span class="dv">3</span>} =&gt; std::cout &lt;&lt; <span class="st">&quot;The &quot;</span> &lt;&lt; d &lt;&lt; <span class="st">&quot; double goes with the 3 int&quot;</span> &lt;&lt; std::endl;
}</code></pre></div>
<h3 id="pattern-matching-variant-like-types">Pattern matching variant-like types</h3>
<p>We would also like to generalize matching for variant-like types. Our example is an <code>either</code> template. It is the variant analogue to <code>std::pair</code>.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;<span class="kw">class</span> T1, <span class="kw">class</span> T2&gt;
lvariant either {
  T1 left;
  T2 right;
};</code></pre></div>
<p>Of course, the above implementation will pattern match without modification since we are using an <code>lvariant</code>. Let us consider, for the sake of discussion, that the data type was implemented as follows:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span>&lt;<span class="kw">typename</span> T, <span class="kw">typename</span> U&gt;
<span class="kw">class</span> either
{
<span class="kw">public</span>:
  <span class="kw">enum</span> selection { left, right };
<span class="kw">private</span>:
  selection m_selection;
  T m_left;
  U m_right;
<span class="kw">public</span>:
  either( ) : m_selection( left ) {}

  either( T t ) : m_selection( left ), m_left( t ) {}

  either( U u ) : m_selection( right ), m_right( u ) {}

  <span class="dt">bool</span> selection() <span class="dt">const</span> { <span class="kw">return</span> m_selection; }

  T&amp; get_left() {
    assert( m_selection == left );
    <span class="kw">return</span> m_left;
  }

  U&amp; get_right() {
    assert( m_selection == right );
    <span class="kw">return</span> m_right;
  }

  either&lt;T,U&gt;&amp; <span class="kw">operator</span>=( <span class="dt">const</span> either&lt;T,U&gt;&amp; other ) {
    m_selection = other.m_selection;
    m_left = other.m_left;
    m_right = other.m_right;
  }

  either&lt;T,U&gt;&amp; <span class="kw">operator</span>=( <span class="dt">const</span> T&amp; t ) {
    m_selection = left;
    m_left = t;
  }

  either&lt;T,U&gt;&amp; <span class="kw">operator</span>=( <span class="dt">const</span> U&amp; u ) {
    m_selection = right;
    m_right = u;
  }
};</code></pre></div>
<p>To enable pattern matching for this type, we need to implement two operator overloads: <code>discriminator</code> and <code>alternative</code>.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span>&lt;<span class="kw">typename</span> T, <span class="kw">typename</span> U&gt;
<span class="kw">class</span> either {
  <span class="co">//...</span>

<span class="kw">public</span>:
  <span class="co">//...</span>

  selection <span class="kw">operator</span> discriminator() {
    <span class="kw">return</span> m_selection;
  }

  <span class="kw">operator</span> alternative( std::variant_piece&lt;T, left&gt; x ) {
    x.set(&amp;m_left);
  }

  <span class="kw">operator</span> alternative( std::variant_piece&lt;U, right&gt; x ) {
    x.set(&amp;m_right);
  }
};</code></pre></div>
<p>The <code>discriminator</code> operator overload returns an integral or <code>enum</code> value corresponding to the question of which alternative is currently active.</p>
<p>The <code>alternative</code> operator is an overloaded function taking in a single <code>std::variant_piece</code> parameter. The first template argument of <code>std::variant_piece</code> is the type of that alternative. The second template argument is a value of the return type of <code>discriminator</code> <a href="#fn5" class="footnoteRef" id="fnref5"><sup>5</sup></a>.</p>
<p>Now we have enough information to use our specialized <code>either</code> class in pattern matching:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">either&lt;std::string, <span class="dt">int</span>&gt; e = <span class="co">/* etc. */</span>;

inspect(e) {
  left error_string
    =&gt; std::cout &lt;&lt; <span class="st">&quot;You&#39;ve got an error: &quot;</span> &lt;&lt; error_string &lt;&lt; std::endl;
  right i
    =&gt; std::cout &lt;&lt; <span class="st">&quot;You&#39;ve got the answer &quot;</span> &lt;&lt; i &lt;&lt; std::endl;
}</code></pre></div>
<p>Note that <code>left</code> and <code>right</code> were not qualified as in <code>either::left</code> and <code>either::right</code>. The intent in our design is that discriminators in class scope are directly available from within <code>inspect</code> statements.</p>
<h2 id="wording-skeleton">Wording Skeleton</h2>
<p>What follows is an incomplete wording for inspection presented for the sake of discussion.</p>
<h3 id="inspect-statement">Inspect Statement</h3>
<p><em>inspect-statement</em>:<br>  <code>inspect</code> <code>(</code> <em>expression</em> <code>)</code> <code>{</code> <em>inspect-statement-cases<sub>opt</sub></em> <code>}</code></p>
<p><em>inspect-statement-cases</em>:<br>  <em>inspect-statement-case</em> <em>inspect-statement-cases<sub>opt</sub></em></p>
<p><em>inspect-statement-case</em>:<br>  <em>guarded-inspect-pattern</em> <code>=&gt;</code> <em>statement</em></p>
<p>The identifiers in <em>inspect-pattern</em> are available in <em>statement</em>.</p>
<p>In the case that none of the patterns match the value, execution continues.</p>
<h3 id="inspect-expression">Inspect Expression</h3>
<p><em>inspect-expression</em>:<br>  <code>inspect</code> <code>(</code> <em>expression</em> <code>)</code> <code>{</code> <em>inspect-expression-cases<sub>opt</sub></em> <code>}</code></p>
<p><em>inspect-expression-cases</em>:<br>  <em>inspect-expression-case</em> <em>inspect-expression-cases<sub>opt</sub></em></p>
<p><em>inspect-expression-case</em>:<br>  <em>guarded-inspect-pattern</em> <code>=&gt;</code> <em>expression</em></p>
<p>The identifiers in <em>inspect-pattern</em> are available in <em>expression</em>.</p>
<p>In the case that none of the patterns match the value, a <code>std::no_match</code> exception is thrown.</p>
<h3 id="inspect-pattern">Inspect Pattern</h3>
<p><em>guarded-inspect-pattern</em>:<br>  <em>inspect-pattern</em> <em>guard<sub>opt</sub></em></p>
<p><em>guard</em>:<br>  <code>if</code> <code>(</code> <em>condition</em> <code>)</code></p>
<p><em>inspect-pattern</em>:<br>  <code>_</code><br>  <code>nullptr</code><br>  <code>*</code> <em>inspect-pattern</em> <br>  <code>(</code> <em>inspect-pattern</em> <code>)</code><br>  <em>identifier</em> ( <code>@</code> <code>(</code> <em>inspect-pattern</em> <code>)</code> )<sub>opt</sub><br>  <em>alternative-selector</em> <em>inspect-pattern</em>  <em>constant-expression</em>  <code>{</code> <em>tuple-like-patterns<sub>opt</sub></em> <code>}</code></p>
<h4 id="wildcard-pattern">Wildcard pattern</h4>
<p><em>inspect-pattern</em>:<br>  <code>_</code><br></p>
<p>The wildcard pattern matches any value and always succeeds.</p>
<h4 id="nullptr-pattern"><code>nullptr</code> pattern</h4>
<p><em>inspect-pattern</em>:<br>  <code>nullptr</code><br></p>
<p>The <code>nullptr</code> pattern matches values <code>v</code> where <code>v == nullptr</code>.</p>
<h4 id="dereference-pattern">Dereference pattern</h4>
<p><em>inspect-pattern</em>:<br>  <code>*</code> <em>inspect-pattern</em> <br></p>
<p>The dereferencing pattern matches values <code>v</code> where <code>v != nullptr</code> and where <code>*v</code> matches the nested pattern.</p>
<h4 id="parenthesis-pattern">Parenthesis pattern</h4>
<p><em>inspect-pattern</em>:<br>  <code>(</code> <em>inspect-pattern</em> <code>)</code><br></p>
<p>The dereferencing pattern matches <em>inspect-pattern</em> and exists for disambiguation.</p>
<h4 id="binding-pattern">Binding pattern</h4>
<p><em>inspect-pattern</em>:<br>  <em>identifier</em> ( <code>@</code> <code>(</code> <em>inspect-pattern</em> <code>)</code> )<sub>opt</sub><br></p>
<p>If <code>@</code> is not used, the binding pattern matches all values and binds the specified identifier to the value being matched. If <code>@</code> is used, the pattern is matched only if the nested pattern matches the value being matched.</p>
<h4 id="alternative-pattern">Alternative pattern</h4>
<p><em>inspect-pattern</em>:<br>  <em>alternative-selector</em> <em>inspect-pattern</em></p>
<p><em>alternative-selector</em>:<br>  <em>constant-expression</em><br>  <em>identifier</em><br></p>
<p>The alternative pattern matches against <code>lvariant</code> values and objects which overload the <code>discriminator</code> and <code>alternative</code> operators. The pattern matches if the value has the appropriate discriminator value and the nested pattern matches the selected alternative.</p>
<p>The <em>constant-expression</em> shall be a converted constant expression (5.20) of the type of the inspect condition's discriminator. The <em>identifier</em> will correspond to a field name if inspect's condition is an <code>lvariant</code> or an identifier that is within scope of the class definition opting into the alternative pattern.</p>
<h4 id="integral-enum-pattern">Integral-enum pattern</h4>
<p><em>inspect-pattern</em>:<br>  <em>constant-expression</em></p>
<p>The integral-enum pattern matches against integral and enum types. The pattern is valid if the matched type is the same as the <em>constant-expression</em> type. The pattern matches if the matched value is the same as the <em>constant-expression</em> value.</p>
<h4 id="tuple-like-patterns">Tuple-like patterns</h4>
<p><em>inspect-pattern</em>:<br>  <code>{</code> <em>tuple-like-patterns<sub>opt</sub></em> <code>}</code></p>
<p><em>tuple-like-patterns</em>:<br>  <em>sequenced-patterns</em><br>  <em>field-patterns</em></p>
<p><em>sequenced-patterns</em>:<br>  <em>inspect-pattern</em> (<code>,</code> <em>sequenced-patterns</em>)<sub>opt</sub></p>
<p><em>field-patterns</em>:<br>  <em>field-pattern</em> (<code>,</code> <em>field-patterns</em>)<sub>opt</sub></p>
<p><em>field-pattern</em>:<br>  <em>piece-selector</em> <code>:</code> <em>inspect-pattern</em></p>
<p><em>piece-selector</em>:<br>  <em>constant-expression</em><br>  <em>identifier</em></p>
<p>Tuple-like patterns come in two varieties: a sequence of patterns and field patterns.</p>
<p>A sequenced pattern is valid if the following conditions are true:</p>
<ol style="list-style-type: decimal">
<li>The matched type is either a <code>class</code> with all public member variables or has a valid extract operator. Say the number of variables or arguments to extract is <code>n</code>.</li>
<li>There are exactly <code>n</code> patterns in the sequence.</li>
<li>Each of the sequenced patterns is valid for the corresponding piece in the matched value.</li>
</ol>
<p>A field pattern is valid if the following conditions are true: 1. The matched type is either a <code>class</code> with all public member variables or has a valid extract operator. 2. <em>piece-selector</em>s, if they are <em>constant-expression</em>, must have the same type as the extract operator's <code>std::tuple_piece</code>s second template argument. 3. <em>piece-selector</em>s, if they are <em>identifier</em>s, must correspond to field names in the <code>class</code> with all public member variables. 4. Each of the field patterns is valid for the the corresponding piece in the matched value.</p>
<p>Both patterns match if the pattern for each piece matches its corresponding piece.</p>
<p>The <em>constant-expression</em> shall be a converted constant expression (5.20) of the type of the inspect condition's extract piece discriminator. The <em>identifier</em> will correspond to a field name if inspect's condition is an class or an identifier that is within scope of the class definition opting into the tuple-like pattern.</p>
<h2 id="design-choices">Design Choices</h2>
<h3 id="inspect-as-a-statement-and-an-expression"><code>inspect</code> as a statement and an expression</h3>
<p>If <code>inspect</code> were a statement-only, it could be used in expressions via. a lambda function. For example:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">const</span> Vec3 opengl_color = [&amp;c]{
  inspect(c) {
    red    =&gt; <span class="kw">return</span> Vec3(<span class="fl">1.0</span>, <span class="fl">0.0</span>, <span class="fl">0.0</span>)
    yellow =&gt; <span class="kw">return</span> Vec3(<span class="fl">1.0</span>, <span class="fl">1.0</span>, <span class="fl">0.0</span>)
    green  =&gt; <span class="kw">return</span> Vec3(<span class="fl">0.0</span>, <span class="fl">1.0</span>, <span class="fl">0.0</span>)
    blue   =&gt; <span class="kw">return</span> Vec3(<span class="fl">0.0</span>, <span class="fl">0.0</span>, <span class="fl">1.0</span>)
  } }();</code></pre></div>
<p>Because we expect that <code>inspect</code> expressions will be the most common use case, we feel the syntactic overhead and tie-in to another complex feature (lambdas) too much to ask from users.</p>
<h3 id="inspect-with-multiple-arguments"><code>inspect</code> with multiple arguments</h3>
<p>It is a straightforward extension of the above syntax to allow for inspecting multiple values at the same time.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">lvariant tree {
  <span class="dt">int</span> leaf;
  std::pair&lt; std::unique_ptr&lt;tree&gt;, std::unique_ptr&lt;tree&gt; &gt; branch;
}

<span class="dt">bool</span> sameStructure(<span class="dt">const</span> tree&amp; lhs, <span class="dt">const</span> tree&amp; rhs) {
  <span class="kw">return</span> inspect(lhs, rhs) {
           {leaf _, leaf _} =&gt; <span class="kw">true</span>
           {branch {*lhs_left, *lhs_right}, branch {*rhs_left, *rhs_right}}
             =&gt;    sameStructure(lhs_left , rhs_left)
                &amp;&amp; samestructure(lhs_right, rhs_right)
           _ =&gt; <span class="kw">false</span>
         };
}</code></pre></div>
<p>It is our intent that the final wording will allow for such constructions.</p>
<h3 id="special-operator-extension-mechanism">Special operator extension mechanism</h3>
<p>The committee has discussed several mechanisms that enable user-defined tuple-like types to opt-in to language features. This is discussed at length in P0326R0 and P0327R0. We present the <code>extract</code>, <code>discriminator</code>, and <code>alternative</code> operators as one such option, but we fully expect that only one mechanism should be ultimately available in the standard.</p>
<h3 id="or-for-tuple-like-access">[] or {} for tuple-like access</h3>
<p>We use curly braces to extract pieces from tuple-like objects because it closely resembles curly brace initialization of tuple-like objects. There has been some discussion as to whether square brackets are a more appropriate choice for structured binding due to ambiguity issues.</p>
<p>Although our preference is curly braces, we believe that whatever is ultimately decided for structured binding should be mimicked here for consistency.</p>
<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. And with language-based variants comes pattern matching, another highly desirable feature in the language.</p>
<h2 id="acknowledgements">Acknowledgements</h2>
<p>Thanks to Vicente Botet Escribá, John Skaller, Dave Abrahams, Bjarne Stroustrup, Bengt Gustafsson, and the C++ committee as a whole for productive design discussions. Also, Yuriy Solodkyy, Gabriel Dos Reis, and Bjarne Stroustrup's prior research into generalized pattern matching as a C++ library has been very helpful.</p>
<h2 id="references">References</h2>
<ul>
<li>V. Botet Escribá. Product types access. P0327R0. WG21</li>
<li>V. Botet Escribá. Structured binding: customization points issues. P0326R0. WG21</li>
<li>A. Naumann. Variant: a type-safe union for C++17 (v7). <a href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0088r2.html">P088R2</a>. WG21.</li>
<li>D. Sankel. <a href="http://davidsankel.com/uncategorized/c-language-support-for-pattern-matching-and-variants/">C++ Langauge Support for Pattern Matching and Variants</a>. davidsankel.com.</li>
<li>Y. Solodkyy, G. Dos Reis, B. Stroustrup. <a href="http://www.stroustrup.com/OpenPatternMatching.pdf">Open Pattern Matching for C++</a>. GPCE 2013.</li>
<li>H. Sutter, B. Stroustrup, G. Dos Reis. Structured bindings. <a href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0144r2.pdf">P0144R2</a>. WG21.</li>
</ul>
<div class="footnotes">
<hr />
<ol>
<li id="fn1"><p>The <code>std::monostate</code> type, which has only one value, is from variant proposal P088R2.<a href="#fnref1">↩</a></p></li>
<li id="fn2"><p>Variant: a type-safe union for C++17 (v7). <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0088r2.html">P0088R2</a><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 lvariant:</p>
<pre><code>lvariant 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>This syntax will only work if <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0127r1.html">P0127R1</a> goes into the language, which seems likely. Otherwise, we would need to explicitly specify the discriminator type as in <code>std::variant_piece&lt;T, selection, left&gt;</code>.<a href="#fnref5">↩</a></p></li>
</ol>
</div>
</body>
</html>
