{"id":6226,"date":"2021-09-23T06:58:50","date_gmt":"2021-09-23T06:58:50","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/visiting-a-std-variant-with-the-overload-pattern\/"},"modified":"2021-09-23T06:58:50","modified_gmt":"2021-09-23T06:58:50","slug":"visiting-a-std-variant-with-the-overload-pattern","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/visiting-a-std-variant-with-the-overload-pattern\/","title":{"rendered":"Visiting a std::variant with the Overload Pattern"},"content":{"rendered":"<p>Typically, you use the overload pattern for a<code> std::variant<\/code>. <code>std::variant<\/code> is a type-safe union. A<code> <\/code><code>std::variant<\/code> (C++17) has one value from one of its types.<code> std::visit<\/code> allows you to apply a visitor to it. Exactly here comes the overload pattern convenient into play.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6208\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/09\/templates.png\" alt=\"templates\" width=\"650\" height=\"409\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><\/p>\n<p>In my last post, &#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/smart-tricks-with-fold-expressions\">Smart Tricks with Parameter Packs and Fold Expressions<\/a>&#8220;, I introduced the overload pattern as a smart trick to create an overload set using lambdas. Typically, the overload pattern is used for visiting the value held by a<code> std::variant<\/code>.<\/p>\n<p>I know from my C++ seminars that most developers don&#8217;t know <code>std::variant<\/code> and<code> std::visit<\/code> and still, use a union. Therefore, let me give you a quick reminder about <code>std::variant<\/code> and <code>std::visit<\/code>.<\/p>\n<h2><code>std::variant (C++17)<br \/><\/code><\/h2>\n<p>A <span style=\"font-family: courier new,courier;\">std::variant<\/span> is a type-safe union. An instance of <span style=\"font-family: courier new,courier;\">std::variant<\/span> has a value from one of its types. The value must not be a reference, C-array, or <span style=\"font-family: courier new,courier;\">void.<\/span> A std::variant can have one type more than once. A default-initialized <span style=\"font-family: courier new,courier;\">std::variant<\/span> will be initialized with its first type. In this case, the first type must have a default constructor. Here is an example based on <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/utility\/variant\">cppreference.com.<\/a>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ variant.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;variant&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;string&gt;<\/span>\r\n \r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>variant<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">float<\/span><span style=\"color: #555555;\">&gt;<\/span> v, w;\r\n  v <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">12<\/span>;                              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> i <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>get<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(v);\r\n  w <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>get<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(v);               <em><span style=\"color: #0099ff;\"> \/\/ (2)<\/span><\/em>\r\n  w <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>get<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">0<\/span><span style=\"color: #555555;\">&gt;<\/span>(v);                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n  w <span style=\"color: #555555;\">=<\/span> v;                               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n \r\n  <span style=\"color: #0099ff; font-style: italic;\">\/\/  std::get&lt;double&gt;(v);             \/\/ (5) ERROR<\/span>\r\n  <span style=\"color: #0099ff; font-style: italic;\">\/\/  std::get&lt;3&gt;(v);                  \/\/ (6) ERROR<\/span>\r\n \r\n  try{\r\n    std<span style=\"color: #555555;\">::<\/span>get<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">float<\/span><span style=\"color: #555555;\">&gt;<\/span>(w);                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (7)<\/span>\r\n  }\r\n  <span style=\"color: #006699; font-weight: bold;\">catch<\/span> (std<span style=\"color: #555555;\">::<\/span>bad_variant_access<span style=\"color: #555555;\">&amp;<\/span>) {}\r\n \r\n  std<span style=\"color: #555555;\">::<\/span>variant<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&gt;<\/span> v(<span style=\"color: #cc3300;\">\"abc\"<\/span>);  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (8)<\/span>\r\n  v <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"def\"<\/span>;                           <span style=\"color: #0099ff; font-style: italic;\">\/\/ (9)<\/span>\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I define both variants <span style=\"font-family: courier new,courier;\">v<\/span> and<span style=\"font-family: courier new,courier;\"> w<\/span>. They can have an <span style=\"font-family: courier new,courier;\">int<\/span> and a <span style=\"font-family: courier new,courier;\">float<\/span> value. Their initial value is 0. <span style=\"font-family: courier new,courier;\">v<\/span> becomes 12 (line 1). <span style=\"font-family: courier new,courier;\">std::get&lt;int&gt;(v)<\/span> returns the value. In lines (2) &#8211; (3), you see three possibilities to assign variant <span style=\"font-family: courier new,courier;\">v<\/span> the variant <span style=\"font-family: courier new,courier;\">w.<\/span> But you have to keep a few rules in mind. You can ask for the value of a variant by type (line 5) or index (line 6). The type must be unique and the index valid. On line 7, the variant <span style=\"font-family: courier new,courier;\">w<\/span> holds an <span style=\"font-family: courier new,courier;\">int<\/span> value. Therefore, I get a <span style=\"font-family: courier new,courier;\">std::bad_variant_access<\/span> exception. If the constructor or assignment call is unambiguous, a simple conversion occurs. That is the reason that it&#8217;s possible to construct a <span style=\"font-family: courier new,courier;\">std::variant&lt;std::string&gt;<\/span> in line (8) with a C-string or assign a new C-string to the variant (line 9).<\/p>\n<p>Of course, there is way more about<code> std::variant.<\/code> Read the post &#8220;<a href=\"https:\/\/www.cppstories.com\/2018\/06\/variant\/\">Everything You Need to Know About std::variant from C++17<\/a>&#8221; by Bartlomiej Filipek.<\/p>\n<p>Thanks to the function <code>std::visit<\/code>, C++17 provides a convenient way to visit the elements of a<code> std::variant<\/code>.<\/p>\n<\/p>\n<h2><code>std::visit<\/code><\/h2>\n<p>According to the classical design patterns, what sounds like the visitor pattern is a kind of visitor for a container of variants.<\/p>\n<p><span style=\"font-family: courier new,courier;\">std::visit<\/span> allows you to apply a visitor to a container of variants. The visitor must be callable. A callable is something that you can invoke. Typical callables are functions, function objects, or lambdas. I use lambdas in my example.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ visitVariants.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;typeinfo&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;variant&gt;<\/span>\r\n\r\n  \r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n  \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n    std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>variant<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">char<\/span>, <span style=\"color: #007788; font-weight: bold;\">long<\/span>, <span style=\"color: #007788; font-weight: bold;\">float<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">double<\/span>, <span style=\"color: #007788; font-weight: bold;\">long<\/span> <span style=\"color: #007788; font-weight: bold;\">long<\/span><span style=\"color: #555555;\">&gt;&gt;<\/span>      <span style=\"color: #0099ff; font-style: italic;\">\/\/ 1<\/span>\r\n               vecVariant <span style=\"color: #555555;\">=<\/span> {<span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #cc3300;\">'2'<\/span>, <span style=\"color: #ff6600;\">5.4<\/span>, <span style=\"color: #ff6600;\">100ll<\/span>, <span style=\"color: #ff6600;\">2011l<\/span>, <span style=\"color: #ff6600;\">3.5f<\/span>, <span style=\"color: #ff6600;\">2017<\/span>};\r\n  \r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> v<span style=\"color: #555555;\">:<\/span> vecVariant){\r\n        std<span style=\"color: #555555;\">::<\/span>visit([](<span style=\"color: #006699; font-weight: bold;\">auto<\/span> arg){std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> arg <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;}, v);                <span style=\"color: #0099ff; font-style: italic;\">\/\/ 2<\/span>\r\n    }\r\n  \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> v<span style=\"color: #555555;\">:<\/span> vecVariant){\r\n        std<span style=\"color: #555555;\">::<\/span>visit([](<span style=\"color: #006699; font-weight: bold;\">auto<\/span> arg){std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(arg).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;}, v); <span style=\"color: #0099ff; font-style: italic;\">\/\/ 3<\/span>\r\n    }\r\n  \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"\\n\\n\"<\/span>;\r\n  \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I create in (1) a<span style=\"font-family: courier new,courier;\"> std::vector<\/span> of variants and initialize each variant. Each variant can hold a <span style=\"font-family: courier new,courier;\">char, long, float, int, double,<\/span> or<span style=\"font-family: courier new,courier;\"> long long value. <\/span>It&#8217;s pretty easy to traverse the vector of variants and apply the lambda (lines (2) and (3) to it. First, I display the current value (2), and second, thanks to the call <span style=\"font-family: courier new,courier;\">typeid(arg).name()<\/span> (3), I get a string representation of the type of the current value.<span style=\"font-family: courier new,courier;\"><\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6222\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/09\/visitVariants.png\" alt=\"visitVariants\" width=\"350\" height=\"203\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/09\/visitVariants.png 394w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/09\/visitVariants-300x174.png 300w\" sizes=\"auto, (max-width: 350px) 100vw, 350px\" \/><\/p>\n<p>Fine? No!. I used it in the program <code>visitVariant.cpp<\/code> generic lambda. Consequently, the string representations of the types are pretty unreadable using GCC: &#8220;<code>i c d x l f i<\/code>&#8220;. Honestly, I want to apply a specific lambda to each type of the variant. Now, the overload pattern comes to my rescue.<\/p>\n<h3>Overload Pattern<\/h3>\n<p>Thanks to the overload pattern, I can display each type with a readable string and display each value in an appropriate way.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ visitVariantsOverloadPattern.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;typeinfo&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;variant&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;string&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> ... Ts<span style=\"color: #555555;\">&gt;<\/span>                                                 <em><span style=\"color: #0099ff;\">\/\/ (7)<\/span> <\/em>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Overload <span style=\"color: #555555;\">:<\/span> Ts ... { \r\n    <span style=\"color: #006699; font-weight: bold;\">using<\/span> Ts<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">operator<\/span>() ...;\r\n};\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span>class... Ts<span style=\"color: #555555;\">&gt;<\/span> Overload(Ts...) <span style=\"color: #555555;\">-&gt;<\/span> Overload<span style=\"color: #555555;\">&lt;<\/span>Ts...<span style=\"color: #555555;\">&gt;<\/span>;\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n  \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n    std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>variant<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">char<\/span>, <span style=\"color: #007788; font-weight: bold;\">long<\/span>, <span style=\"color: #007788; font-weight: bold;\">float<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">double<\/span>, <span style=\"color: #007788; font-weight: bold;\">long<\/span> <span style=\"color: #007788; font-weight: bold;\">long<\/span><span style=\"color: #555555;\">&gt;&gt;<\/span>  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)    <\/span>\r\n               vecVariant <span style=\"color: #555555;\">=<\/span> {<span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #cc3300;\">'2'<\/span>, <span style=\"color: #ff6600;\">5.4<\/span>, <span style=\"color: #ff6600;\">100ll<\/span>, <span style=\"color: #ff6600;\">2011l<\/span>, <span style=\"color: #ff6600;\">3.5f<\/span>, <span style=\"color: #ff6600;\">2017<\/span>};\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> TypeOfIntegral <span style=\"color: #555555;\">=<\/span> Overload {                                      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n        [](<span style=\"color: #007788; font-weight: bold;\">char<\/span>) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #cc3300;\">\"char\"<\/span>; },\r\n        [](<span style=\"color: #007788; font-weight: bold;\">int<\/span>) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #cc3300;\">\"int\"<\/span>; },\r\n        [](<span style=\"color: #007788; font-weight: bold;\">unsigned<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span>) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #cc3300;\">\"unsigned int\"<\/span>; },\r\n        [](<span style=\"color: #007788; font-weight: bold;\">long<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span>) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #cc3300;\">\"long int\"<\/span>; },\r\n        [](<span style=\"color: #007788; font-weight: bold;\">long<\/span> <span style=\"color: #007788; font-weight: bold;\">long<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span>) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #cc3300;\">\"long long int\"<\/span>; },\r\n        [](<span style=\"color: #006699; font-weight: bold;\">auto<\/span>) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #cc3300;\">\"unknown type\"<\/span>; },\r\n    };\r\n  \r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> v <span style=\"color: #555555;\">:<\/span> vecVariant) {                                           <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>visit(TypeOfIntegral, v) <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    }\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>variant<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>, <span style=\"color: #007788; font-weight: bold;\">double<\/span>, std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&gt;&gt;<\/span>      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n        vecVariant2 <span style=\"color: #555555;\">=<\/span> { <span style=\"color: #ff6600;\">1.5<\/span>, std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>}, <span style=\"color: #cc3300;\">\"Hello \"<\/span>};\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> DisplayMe <span style=\"color: #555555;\">=<\/span> Overload {                                           <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n        [](std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;&amp;<\/span> myVec) { \r\n                <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> v<span style=\"color: #555555;\">:<\/span> myVec) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> v <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;\r\n                std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>; \r\n            },\r\n        [](<span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> arg) { std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> arg <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;},\r\n    };\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> v <span style=\"color: #555555;\">:<\/span> vecVariant2) {                                         <span style=\"color: #0099ff; font-style: italic;\">\/\/ (6)<\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>visit(DisplayMe, v);\r\n    }\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Line (1) creates a vector of variants having integral types, and line (4) creates a vector of variants having a <code>std::vector&lt;int&gt;<\/code>,<code> double<\/code>, and a <code>std::string<\/code>.<\/p>\n<p>Let me continue with the first variant<code> vecVariant<\/code>. TypeOfIntegral (2) is an overload set that returns for a few integral types a string representation. If the type is not handled by the overload set, I return the string &#8220;<code>unknown type<\/code>&#8220;. In line (3), I apply the overload set to each variant<code> v<\/code> using<code> std::visit<\/code>.<\/p>\n<p>The second variant vecVariant2 (4), has composed types. I create an overload set (5) to display their values. In general, I can just push the value onto<code> std:.cout<\/code>. For the<code> std::vector&lt;int&gt;<\/code>, I use a range-based for-loop to push its values to<code> std::cout<\/code>.<\/p>\n<p>Finally, here is the output of the program.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6223\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/09\/visitVariantsOverloadPattern.png\" alt=\"visitVariantsOverloadPattern\" width=\"494\" height=\"417\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/09\/visitVariantsOverloadPattern.png 494w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/09\/visitVariantsOverloadPattern-300x253.png 300w\" sizes=\"auto, (max-width: 494px) 100vw, 494px\" \/><\/p>\n<p>I want to add a few words to the overload pattern used in this example (7). I already introduced in my last post, &#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/smart-tricks-with-fold-expressions\">Smart Tricks with Parameter Packs and Fold Expressions<\/a>`.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> ... Ts<span style=\"color: #555555;\">&gt;<\/span>                                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Overload <span style=\"color: #555555;\">:<\/span> Ts ... { \r\n    <span style=\"color: #006699; font-weight: bold;\">using<\/span> Ts<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">operator<\/span>() ...;\r\n};\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span>class... Ts<span style=\"color: #555555;\">&gt;<\/span> Overload(Ts...) <span style=\"color: #555555;\">-&gt;<\/span> Overload<span style=\"color: #555555;\">&lt;<\/span>Ts...<span style=\"color: #555555;\">&gt;<\/span>; <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Line (1) is the overload pattern, and line (2) is the deduction guide. The struct <code>Overload<\/code> can have arbitrarily many base classes (<code>Ts ...<\/code>). It derives from each class <code>public<\/code> and brings the call operator (<code>Ts::operator..<\/code>.) of each base class into its scope. The base classes need an overloaded call operator (Ts::operator()). Lambdas provide this call operator. The following example is as simple as it can be.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #009999;\">#include &lt;variant&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> ... Ts<span style=\"color: #555555;\">&gt;<\/span>                                                 \r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Overload <span style=\"color: #555555;\">:<\/span> Ts ... { \r\n    <span style=\"color: #006699; font-weight: bold;\">using<\/span> Ts<span style=\"color: #555555;\">::<\/span><span style=\"color: #006699; font-weight: bold;\">operator<\/span>() ...;\r\n};\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span>class... Ts<span style=\"color: #555555;\">&gt;<\/span> Overload(Ts...) <span style=\"color: #555555;\">-&gt;<\/span> Overload<span style=\"color: #555555;\">&lt;<\/span>Ts...<span style=\"color: #555555;\">&gt;<\/span>;\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n  \r\n    std<span style=\"color: #555555;\">::<\/span>variant<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">char<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">float<\/span><span style=\"color: #555555;\">&gt;<\/span> var <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">2017<\/span>;\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> TypeOfIntegral <span style=\"color: #555555;\">=<\/span> Overload {    <em><span style=\"color: #0099ff;\"> \/\/ (1) <\/span><\/em>                                 \r\n        [](<span style=\"color: #007788; font-weight: bold;\">char<\/span>) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #cc3300;\">\"char\"<\/span>; },\r\n        [](<span style=\"color: #007788; font-weight: bold;\">int<\/span>) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #cc3300;\">\"int\"<\/span>; },\r\n        [](<span style=\"color: #006699; font-weight: bold;\">auto<\/span>) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #cc3300;\">\"unknown type\"<\/span>; },\r\n    };\r\n  \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Using this<a href=\"https:\/\/cppinsights.io\/s\/70167530\"> example in C++ Insights<\/a> makes the magic transparent. First, call (1) causes the creation of a fully specialized class template.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6224\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/09\/OverloadPatternInstantiated.png\" alt=\"OverloadPatternInstantiated\" width=\"650\" height=\"235\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/09\/OverloadPatternInstantiated.png 907w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/09\/OverloadPatternInstantiated-300x108.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/09\/OverloadPatternInstantiated-768x278.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>Second, the used lambdas in the overload pattern such as<code> [](char) { return \"char\"; }<\/code> cause the creation of a function object. In this case, the compiler gives the function object the name<code> __lambda_15_9<\/code>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6225\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/09\/lambdaChar.png\" alt=\"lambdaChar\" width=\"668\" height=\"447\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/09\/lambdaChar.png 668w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/09\/lambdaChar-300x201.png 300w\" sizes=\"auto, (max-width: 668px) 100vw, 668px\" \/><\/p>\n<p>Studying the auto-generate types show at least one interesting point. The call operator of __lambda_15_9 is overloaded for<code> char: const char * operator() (char) const { return \"char\"; }<\/code><\/p>\n<p>The deduction guide (<code>template&lt;class... Ts&gt; Overload(Ts...) -&gt; Overload&lt;Ts...&gt;;<\/code>) (line 2) is only needed for C++17. The deduction guide tells the compiler how to create out-of-constructor arguments template parameters. C++20 can automatically deduce the template.&nbsp;<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>The friendship of templates is special. In my next post, I will explain why.<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<div id=\"simple-translate\">\n<div>\n<div class=\"simple-translate-button isShow\" style=\"background-image: url('moz-extension:\/\/981aa874-2db4-44d3-a97f-b02a72476831\/icons\/512.png'); height: 22px; width: 22px; top: 213px; left: 511px;\">&nbsp;<\/div>\n<div class=\"simple-translate-panel\" style=\"width: 300px; height: 200px; top: 0px; left: 0px; font-size: 13px; background-color: #ffffff;\">\n<div class=\"simple-translate-result-wrapper\" style=\"overflow: hidden;\">\n<div class=\"simple-translate-move\" draggable=\"draggable\">&nbsp;<\/div>\n<div class=\"simple-translate-result-contents\">\n<p class=\"simple-translate-result\" dir=\"auto\" style=\"color: #000000;\">&nbsp;<\/p>\n<p class=\"simple-translate-candidate\" dir=\"auto\" style=\"color: #737373;\">&nbsp;<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Typically, you use the overload pattern for a std::variant. std::variant is a type-safe union. A std::variant (C++17) has one value from one of its types. std::visit allows you to apply a visitor to it. Exactly here comes the overload pattern convenient into play.<\/p>\n","protected":false},"author":21,"featured_media":6208,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[376],"tags":[],"class_list":["post-6226","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-templates"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6226","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=6226"}],"version-history":[{"count":0,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6226\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/6208"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6226"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6226"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6226"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}