5 <!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <meta name="generator" content="Asciidoctor 1.5.8">
8 <meta name="author" content="Peter Dimov">
9 <title>Boost.Variant2: A never valueless variant type</title>
10 <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
12 /* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
13 /* Uncomment @import statement below to use as custom stylesheet */
14 /*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
15 article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
16 audio,canvas,video{display:inline-block}
17 audio:not([controls]){display:none;height:0}
18 script{display:none!important}
19 html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
20 a{background:transparent}
21 a:focus{outline:thin dotted}
22 a:active,a:hover{outline:0}
23 h1{font-size:2em;margin:.67em 0}
24 abbr[title]{border-bottom:1px dotted}
25 b,strong{font-weight:bold}
26 dfn{font-style:italic}
27 hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
28 mark{background:#ff0;color:#000}
29 code,kbd,pre,samp{font-family:monospace;font-size:1em}
30 pre{white-space:pre-wrap}
31 q{quotes:"\201C" "\201D" "\2018" "\2019"}
33 sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
37 svg:not(:root){overflow:hidden}
39 fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
40 legend{border:0;padding:0}
41 button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
42 button,input{line-height:normal}
43 button,select{text-transform:none}
44 button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
45 button[disabled],html input[disabled]{cursor:default}
46 input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
47 button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
48 textarea{overflow:auto;vertical-align:top}
49 table{border-collapse:collapse;border-spacing:0}
50 *,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
51 html,body{font-size:100%}
52 body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
53 a:hover{cursor:pointer}
54 img,object,embed{max-width:100%;height:auto}
55 object,embed{height:100%}
56 img{-ms-interpolation-mode:bicubic}
57 .left{float:left!important}
58 .right{float:right!important}
59 .text-left{text-align:left!important}
60 .text-right{text-align:right!important}
61 .text-center{text-align:center!important}
62 .text-justify{text-align:justify!important}
64 img,object,svg{display:inline-block;vertical-align:middle}
65 textarea{height:auto;min-height:50px}
67 .center{margin-left:auto;margin-right:auto}
69 .subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
70 div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
71 a{color:#2156a5;text-decoration:underline;line-height:inherit}
72 a:hover,a:focus{color:#1d4b8f}
74 p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
75 p aside{font-size:.875em;line-height:1.35;font-style:italic}
76 h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
77 h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
79 h2{font-size:1.6875em}
80 h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
81 h4,h5{font-size:1.125em}
83 hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
84 em,i{font-style:italic;line-height:inherit}
85 strong,b{font-weight:bold;line-height:inherit}
86 small{font-size:60%;line-height:inherit}
87 code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
88 ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
89 ul,ol{margin-left:1.5em}
90 ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
91 ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
92 ul.square{list-style-type:square}
93 ul.circle{list-style-type:circle}
94 ul.disc{list-style-type:disc}
95 ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
96 dl dt{margin-bottom:.3125em;font-weight:bold}
97 dl dd{margin-bottom:1.25em}
98 abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
99 abbr{text-transform:none}
100 blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
101 blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
102 blockquote cite::before{content:"\2014 \0020"}
103 blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
104 blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
105 @media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
107 h2{font-size:2.3125em}
108 h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
109 h4{font-size:1.4375em}}
110 table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
111 table thead,table tfoot{background:#f7f8f7}
112 table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
113 table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
114 table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
115 table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
116 h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
117 h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
118 .clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
119 .clearfix::after,.float-group::after{clear:both}
120 *:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}
121 *:not(pre)>code.nobreak{word-wrap:normal}
122 *:not(pre)>code.nowrap{white-space:nowrap}
123 pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
124 em em{font-style:normal}
125 strong strong{font-weight:400}
126 .keyseq{color:rgba(51,51,51,.8)}
127 kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
128 .keyseq kbd:first-child{margin-left:0}
129 .keyseq kbd:last-child{margin-right:0}
130 .menuseq,.menuref{color:#000}
131 .menuseq b:not(.caret),.menuref{font-weight:inherit}
132 .menuseq{word-spacing:-.02em}
133 .menuseq b.caret{font-size:1.25em;line-height:.8}
134 .menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
135 b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
136 b.button::before{content:"[";padding:0 3px 0 2px}
137 b.button::after{content:"]";padding:0 2px 0 3px}
138 p a>code:hover{color:rgba(0,0,0,.9)}
139 #header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
140 #header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
141 #header::after,#content::after,#footnotes::after,#footer::after{clear:both}
142 #content{margin-top:1.25em}
143 #content::before{content:none}
144 #header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
145 #header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
146 #header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
147 #header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
148 #header .details span:first-child{margin-left:-.125em}
149 #header .details span.email a{color:rgba(0,0,0,.85)}
150 #header .details br{display:none}
151 #header .details br+span::before{content:"\00a0\2013\00a0"}
152 #header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
153 #header .details br+span#revremark::before{content:"\00a0|\00a0"}
154 #header #revnumber{text-transform:capitalize}
155 #header #revnumber::after{content:"\00a0"}
156 #content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
157 #toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
158 #toc>ul{margin-left:.125em}
159 #toc ul.sectlevel0>li>a{font-style:italic}
160 #toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
161 #toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
162 #toc li{line-height:1.3334;margin-top:.3334em}
163 #toc a{text-decoration:none}
164 #toc a:active{text-decoration:underline}
165 #toctitle{color:#7a2518;font-size:1.2em}
166 @media screen and (min-width:768px){#toctitle{font-size:1.375em}
167 body.toc2{padding-left:15em;padding-right:0}
168 #toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
169 #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
170 #toc.toc2>ul{font-size:.9em;margin-bottom:0}
171 #toc.toc2 ul ul{margin-left:0;padding-left:1em}
172 #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
173 body.toc2.toc-right{padding-left:0;padding-right:15em}
174 body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
175 @media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
176 #toc.toc2{width:20em}
177 #toc.toc2 #toctitle{font-size:1.375em}
178 #toc.toc2>ul{font-size:.95em}
179 #toc.toc2 ul ul{padding-left:1.25em}
180 body.toc2.toc-right{padding-left:0;padding-right:20em}}
181 #content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
182 #content #toc>:first-child{margin-top:0}
183 #content #toc>:last-child{margin-bottom:0}
184 #footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
185 #footer-text{color:rgba(255,255,255,.8);line-height:1.44}
186 #content{margin-bottom:.625em}
187 .sect1{padding-bottom:.625em}
188 @media screen and (min-width:768px){#content{margin-bottom:1.25em}
189 .sect1{padding-bottom:1.25em}}
190 .sect1:last-child{padding-bottom:0}
191 .sect1+.sect1{border-top:1px solid #e7e7e9}
192 #content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
193 #content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
194 #content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
195 #content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
196 #content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
197 .audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
198 .admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
199 table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
200 .paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
201 table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit}
202 .admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
203 .admonitionblock>table td.icon{text-align:center;width:80px}
204 .admonitionblock>table td.icon img{max-width:none}
205 .admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
206 .admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6)}
207 .admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
208 .exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
209 .exampleblock>.content>:first-child{margin-top:0}
210 .exampleblock>.content>:last-child{margin-bottom:0}
211 .sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
212 .sidebarblock>:first-child{margin-top:0}
213 .sidebarblock>:last-child{margin-bottom:0}
214 .sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
215 .exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
216 .literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
217 .sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
218 .literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;overflow-x:auto;padding:1em;font-size:.8125em}
219 @media screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
220 @media screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
221 .literalblock pre.nowrap,.literalblock pre.nowrap pre,.listingblock pre.nowrap,.listingblock pre.nowrap pre{white-space:pre;word-wrap:normal}
222 .literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
223 .listingblock pre.highlightjs{padding:0}
224 .listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
225 .listingblock pre.prettyprint{border-width:0}
226 .listingblock>.content{position:relative}
227 .listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
228 .listingblock:hover code[data-lang]::before{display:block}
229 .listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:#999}
230 .listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
231 table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
232 table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
233 table.pyhltable td.code{padding-left:.75em;padding-right:0}
234 pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #dddddf}
235 pre.pygments .lineno{display:inline-block;margin-right:.25em}
236 table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
237 .quoteblock{margin:0 1em 1.25em 1.5em;display:table}
238 .quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
239 .quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
240 .quoteblock blockquote{margin:0;padding:0;border:0}
241 .quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
242 .quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
243 .quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
244 .verseblock{margin:0 1em 1.25em}
245 .verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
246 .verseblock pre strong{font-weight:400}
247 .verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
248 .quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
249 .quoteblock .attribution br,.verseblock .attribution br{display:none}
250 .quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
251 .quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
252 .quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
253 .quoteblock.abstract{margin:0 1em 1.25em;display:block}
254 .quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
255 .quoteblock.excerpt,.quoteblock .quoteblock{margin:0 0 1.25em;padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
256 .quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
257 .quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0}
258 table.tableblock{max-width:100%;border-collapse:separate}
259 p.tableblock:last-child{margin-bottom:0}
260 td.tableblock>.content{margin-bottom:-1.25em}
261 table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
262 table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}
263 table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}
264 table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}
265 table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px}
266 table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0}
267 table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}
268 table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0}
269 table.frame-all{border-width:1px}
270 table.frame-sides{border-width:0 1px}
271 table.frame-topbot,table.frame-ends{border-width:1px 0}
272 table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd){background:#f8f8f7}
273 table.stripes-none tr,table.stripes-odd tr:nth-of-type(even){background:none}
274 th.halign-left,td.halign-left{text-align:left}
275 th.halign-right,td.halign-right{text-align:right}
276 th.halign-center,td.halign-center{text-align:center}
277 th.valign-top,td.valign-top{vertical-align:top}
278 th.valign-bottom,td.valign-bottom{vertical-align:bottom}
279 th.valign-middle,td.valign-middle{vertical-align:middle}
280 table thead th,table tfoot th{font-weight:bold}
281 tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
282 tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
283 p.tableblock>code:only-child{background:none;padding:0}
284 p.tableblock{font-size:1em}
285 td>div.verse{white-space:pre}
286 ol{margin-left:1.75em}
287 ul li ol{margin-left:1.5em}
288 dl dd{margin-left:1.125em}
289 dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
290 ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
291 ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
292 ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
293 ul.unstyled,ol.unstyled{margin-left:0}
294 ul.checklist{margin-left:.625em}
295 ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
296 ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}
297 ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
298 ul.inline>li{margin-left:1.25em}
299 .unstyled dl dt{font-weight:400;font-style:normal}
300 ol.arabic{list-style-type:decimal}
301 ol.decimal{list-style-type:decimal-leading-zero}
302 ol.loweralpha{list-style-type:lower-alpha}
303 ol.upperalpha{list-style-type:upper-alpha}
304 ol.lowerroman{list-style-type:lower-roman}
305 ol.upperroman{list-style-type:upper-roman}
306 ol.lowergreek{list-style-type:lower-greek}
307 .hdlist>table,.colist>table{border:0;background:none}
308 .hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
309 td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
310 td.hdlist1{font-weight:bold;padding-bottom:1.25em}
311 .literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
312 .colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
313 .colist td:not([class]):first-child img{max-width:none}
314 .colist td:not([class]):last-child{padding:.25em 0}
315 .thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
316 .imageblock.left{margin:.25em .625em 1.25em 0}
317 .imageblock.right{margin:.25em 0 1.25em .625em}
318 .imageblock>.title{margin-bottom:0}
319 .imageblock.thumb,.imageblock.th{border-width:6px}
320 .imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
321 .image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
322 .image.left{margin-right:.625em}
323 .image.right{margin-left:.625em}
324 a.image{text-decoration:none;display:inline-block}
325 a.image object{pointer-events:none}
326 sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
327 sup.footnote a,sup.footnoteref a{text-decoration:none}
328 sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
329 #footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
330 #footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
331 #footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
332 #footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
333 #footnotes .footnote:last-of-type{margin-bottom:0}
334 #content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
335 .gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
336 .gist .file-data>table td.line-data{width:99%}
337 div.unbreakable{page-break-inside:avoid}
338 .big{font-size:larger}
339 .small{font-size:smaller}
340 .underline{text-decoration:underline}
341 .overline{text-decoration:overline}
342 .line-through{text-decoration:line-through}
344 .aqua-background{background-color:#00fafa}
346 .black-background{background-color:#000}
348 .blue-background{background-color:#0000fa}
349 .fuchsia{color:#bf00bf}
350 .fuchsia-background{background-color:#fa00fa}
352 .gray-background{background-color:#7d7d7d}
353 .green{color:#006000}
354 .green-background{background-color:#007d00}
356 .lime-background{background-color:#00fa00}
357 .maroon{color:#600000}
358 .maroon-background{background-color:#7d0000}
360 .navy-background{background-color:#00007d}
361 .olive{color:#606000}
362 .olive-background{background-color:#7d7d00}
363 .purple{color:#600060}
364 .purple-background{background-color:#7d007d}
366 .red-background{background-color:#fa0000}
367 .silver{color:#909090}
368 .silver-background{background-color:#bcbcbc}
370 .teal-background{background-color:#007d7d}
371 .white{color:#bfbfbf}
372 .white-background{background-color:#fafafa}
373 .yellow{color:#bfbf00}
374 .yellow-background{background-color:#fafa00}
375 span.icon>.fa{cursor:default}
376 a span.icon>.fa{cursor:inherit}
377 .admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
378 .admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
379 .admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
380 .admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
381 .admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
382 .admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
383 .conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
384 .conum[data-value] *{color:#fff!important}
385 .conum[data-value]+b{display:none}
386 .conum[data-value]::after{content:attr(data-value)}
387 pre .conum[data-value]{position:relative;top:-.125em}
388 b.conum *{color:inherit!important}
389 .conum:not([data-value]):empty{display:none}
390 dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
391 h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
392 p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
393 p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
394 p{margin-bottom:1.25rem}
395 .sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
396 .exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
397 .print-only{display:none!important}
398 @page{margin:1.25cm .75cm}
399 @media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
401 a{color:inherit!important;text-decoration:underline!important}
402 a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
403 a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
404 abbr[title]::after{content:" (" attr(title) ")"}
405 pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
406 thead{display:table-header-group}
408 p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
409 h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
410 #toc,.sidebarblock,.exampleblock>.content{background:none!important}
411 #toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
412 body.book #header{text-align:center}
413 body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
414 body.book #header .details{border:0!important;display:block;padding:0!important}
415 body.book #header .details span:first-child{margin-left:0!important}
416 body.book #header .details br{display:block}
417 body.book #header .details br+span::before{content:none!important}
418 body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
419 body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
420 .listingblock code[data-lang]::before{display:block}
421 #footer{padding:0 .9375em}
422 .hide-on-print{display:none!important}
423 .print-only{display:block!important}
424 .hide-for-print{display:none!important}
425 .show-for-print{display:inherit!important}}
426 @media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem}
427 .sect1{padding:0!important}
428 .sect1+.sect1{border:0}
429 #footer{background:none}
430 #footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
431 @media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
434 <body class="article toc2 toc-left">
436 <h1>Boost.Variant2: A never valueless variant type</h1>
437 <div class="details">
438 <span id="author" class="author">Peter Dimov</span><br>
440 <div id="toc" class="toc2">
441 <div id="toctitle">Table of Contents</div>
442 <ul class="sectlevel1">
443 <li><a href="#overview">Overview</a>
444 <ul class="sectlevel2">
445 <li><a href="#overview_description">Description</a></li>
446 <li><a href="#overview_usage_examples">Usage Examples</a></li>
447 <li><a href="#overview_construction_and_assignment">Construction and Assignment</a></li>
448 <li><a href="#overview_inspecting_the_value">Inspecting the Value</a></li>
449 <li><a href="#overview_visitation">Visitation</a></li>
450 <li><a href="#overview_default_construction">Default Construction</a></li>
453 <li><a href="#changelog">Revision History</a>
454 <ul class="sectlevel2">
455 <li><a href="#changelog_changes_in_1_71_0">Changes in 1.71.0</a></li>
458 <li><a href="#design">Design</a>
459 <ul class="sectlevel2">
460 <li><a href="#design_features">Features</a></li>
461 <li><a href="#design_rationale">Rationale</a>
462 <ul class="sectlevel3">
463 <li><a href="#design_never_valueless">Never Valueless</a></li>
464 <li><a href="#design_strong_exception_safety">Strong Exception Safety</a></li>
467 <li><a href="#design_differences_with_stdvariant">Differences with std::variant</a></li>
468 <li><a href="#design_differences_with_boost_variant">Differences with Boost.Variant</a></li>
471 <li><a href="#implementation">Implementation</a>
472 <ul class="sectlevel2">
473 <li><a href="#implementation_dependencies">Dependencies</a></li>
474 <li><a href="#implementation_supported_compilers">Supported Compilers</a></li>
477 <li><a href="#reference">Reference</a>
478 <ul class="sectlevel2">
479 <li><a href="#ref_boostvariant2variant_hpp"><boost/variant2/variant.hpp></a>
480 <ul class="sectlevel3">
481 <li><a href="#ref_synopsis">Synopsis</a></li>
482 <li><a href="#ref_variant">variant</a>
483 <ul class="sectlevel4">
484 <li><a href="#ref_constructors">Constructors</a></li>
485 <li><a href="#ref_destructor">Destructor</a></li>
486 <li><a href="#ref_assignment">Assignment</a></li>
487 <li><a href="#ref_modifiers">Modifiers</a></li>
488 <li><a href="#ref_value_status">Value Status</a></li>
489 <li><a href="#ref_swap">Swap</a></li>
490 <li><a href="#ref_converting_constructors_extension">Converting Constructors (extension)</a></li>
491 <li><a href="#ref_subset_extension">Subset (extension)</a></li>
494 <li><a href="#ref_variant_alternative">variant_alternative</a></li>
495 <li><a href="#ref_holds_alternative">holds_alternative</a></li>
496 <li><a href="#ref_get">get</a></li>
497 <li><a href="#ref_get_if">get_if</a></li>
498 <li><a href="#ref_relational_operators">Relational Operators</a></li>
499 <li><a href="#ref_visit">visit</a></li>
500 <li><a href="#ref_swap_2">swap</a></li>
501 <li><a href="#ref_bad_variant_access">bad_variant_access</a></li>
506 <li><a href="#copyright">Copyright and License</a></li>
512 <h2 id="overview">Overview</h2>
513 <div class="sectionbody">
515 <h3 id="overview_description">Description</h3>
516 <div class="paragraph">
517 <p>This library implements a type-safe discriminated/tagged union type,
518 <code>variant<T…​></code>, that is API-compatible with the C++17 Standard’s
519 <a href="http://en.cppreference.com/w/cpp/utility/variant"><code>std::variant<T…​></code></a>.</p>
521 <div class="paragraph">
522 <p>A <code>variant<T1, T2, …​, Tn></code> variable can hold a value of any of the
523 types <code>T1</code>, <code>T2</code>, …​, <code>Tn</code>. For example,
524 <code>variant<int64_t, double, std::string></code> can hold an <code>int64_t</code> value, a
525 <code>double</code> value, or a <code>string</code> value.</p>
527 <div class="paragraph">
528 <p>Such a type is sometimes called a "tagged union", because it’s roughly
531 <div class="listingblock">
532 <div class="content">
533 <pre class="highlight"><code>struct V
535 enum tag { tag_int64_t, tag_double, tag_string };
550 <h3 id="overview_usage_examples">Usage Examples</h3>
551 <div class="paragraph">
552 <p>Variants can be used to represent dynamically-typed values. A configuration
555 <div class="listingblock">
556 <div class="content">
557 <pre class="highlight"><code>server.host=test.example.com
559 cache.max_load=0.7</code></pre>
562 <div class="paragraph">
563 <p>can be represented as <code>std::map<std::string, variant<int64_t, double,
564 std::string>></code>.</p>
566 <div class="paragraph">
567 <p>Variants can also represent polymorphism. To take a classic example, a
568 polymorphic collection of shapes:</p>
570 <div class="listingblock">
571 <div class="content">
572 <pre class="highlight"><code>#define _USE_MATH_DEFINES
573 #include <iostream>
574 #include <vector>
575 #include <memory>
576 #include <cmath>
582 virtual ~Shape() = default;
583 virtual double area() const = 0;
586 class Rectangle: public Shape
590 double width_, height_;
594 Rectangle( double width, double height ):
595 width_( width ), height_( height ) {}
597 virtual double area() const { return width_ * height_; }
600 class Circle: public Shape
608 explicit Circle( double radius ): radius_( radius ) {}
609 virtual double area() const { return M_PI * radius_ * radius_; }
612 double total_area( std::vector<std::unique_ptr<Shape>> const & v )
616 for( auto const& p: v )
626 std::vector<std::unique_ptr<Shape>> v;
628 v.push_back( std::unique_ptr<Shape>( new Circle( 1.0 ) ) );
629 v.push_back( std::unique_ptr<Shape>( new Rectangle( 2.0, 3.0 ) ) );
631 std::cout << "Total area: " << total_area( v ) << std::endl;
635 <div class="paragraph">
636 <p>can instead be represented as a collection of <code>variant<Rectangle, Circle></code>
637 values. This requires the possible <code>Shape</code> types be known in advance, as is
638 often the case. In return, we no longer need virtual functions, or to allocate
639 the values on the heap with <code>new Rectangle</code> and <code>new Circle</code>:</p>
641 <div class="listingblock">
642 <div class="content">
643 <pre class="highlight"><code>#define _USE_MATH_DEFINES
644 #include <iostream>
645 #include <vector>
646 #include <cmath>
648 #include <boost/variant2/variant.hpp>
649 using namespace boost::variant2;
653 double width_, height_;
654 double area() const { return width_ * height_; }
660 double area() const { return M_PI * radius_ * radius_; }
663 double total_area( std::vector<variant<Rectangle, Circle>> const & v )
667 for( auto const& x: v )
669 s += visit( []( auto const& y ){ return y.area(); }, x );
677 std::vector<variant<Rectangle, Circle>> v;
679 v.push_back( Circle{ 1.0 } );
680 v.push_back( Rectangle{ 2.0, 3.0 } );
682 std::cout << "Total area: " << total_area( v ) << std::endl;
688 <h3 id="overview_construction_and_assignment">Construction and Assignment</h3>
689 <div class="paragraph">
690 <p>If we look at the</p>
692 <div class="listingblock">
693 <div class="content">
694 <pre class="highlight"><code> v.push_back( Circle{ 1.0 } );</code></pre>
697 <div class="paragraph">
698 <p>line, we can deduce that <code>variant<Rectangle, Circle></code> can be (implicitly)
699 constructed from <code>Circle</code> (and <code>Rectangle</code>), and indeed it can. It can also
700 be assigned a <code>Circle</code> or a <code>Rectangle</code>:</p>
702 <div class="listingblock">
703 <div class="content">
704 <pre class="highlight"><code>variant<Rectangle, Circle> v = Circle{ 1.0 }; // v holds Circle
705 v = Rectangle{ 2.0, 3.0 }; // v now holds Rectangle</code></pre>
708 <div class="paragraph">
709 <p>If we try to construct <code>variant<int, float></code> from something that is neither
710 <code>int</code> nor <code>float</code>, say, <code>(short)1</code>, the behavior is "as if" the <code>variant</code> has
711 declared two constructors,</p>
713 <div class="listingblock">
714 <div class="content">
715 <pre class="highlight"><code>variant::variant(int x);
716 variant::variant(float x);</code></pre>
719 <div class="paragraph">
720 <p>and the standard overload resolution rules are used to pick the one that will
721 be used. So <code>variant<int, float>((short)1)</code> will hold an <code>int</code>.</p>
725 <h3 id="overview_inspecting_the_value">Inspecting the Value</h3>
726 <div class="paragraph">
727 <p>Putting values into a <code>variant</code> is easy, but taking them out is necessarily a
728 bit more convoluted. It’s not possible for <code>variant<int, float></code> to define a
729 member function <code>get() const</code>, because such a function will need its return
730 type fixed at compile time, and whether the correct return type is <code>int</code> or
731 <code>float</code> will only become known at run time.</p>
733 <div class="paragraph">
734 <p>There are a few ways around that. First, there is the accessor member function</p>
736 <div class="listingblock">
737 <div class="content">
738 <pre class="highlight"><code>std::size_t variant::index() const noexcept;</code></pre>
741 <div class="paragraph">
742 <p>that returns the zero-based index of the current type. For <code>variant<int,
743 float></code>, it will return <code>0</code> for <code>int</code> and <code>1</code> for <code>float</code>.</p>
745 <div class="paragraph">
746 <p>Once we have the index, we can use the free function <code>get<N></code> to obtain the
747 value. Since we’re passing the type index to <code>get</code>, it knows what to return.
748 <code>get<0>(v)</code> will return <code>int</code>, and <code>get<1>(v)</code> will return <code>float</code>:</p>
750 <div class="listingblock">
751 <div class="content">
752 <pre class="highlight"><code>void f( variant<int, float> const& v )
758 // use get<0>(v)
763 // use get<1>(v)
768 assert(false); // never happens
773 <div class="paragraph">
774 <p>If we call <code>get<0>(v)</code>, and <code>v.index()</code> is not currently <code>0</code>, an exception
775 (of type <code>bad_variant_access</code>) will be thrown.</p>
777 <div class="paragraph">
778 <p>An alternative approach is to use <code>get<int>(v)</code> or <code>get<float>(v)</code>. This
781 <div class="paragraph">
782 <p>Another alternative that avoids the possibility of <code>bad_variant_access</code> is
783 to use <code>get_if</code>. Instead of a reference to the contained value, it returns
784 a pointer to it, returning <code>nullptr</code> to indicate type mismatch. <code>get_if</code>
785 takes a pointer to the <code>variant</code>, so in our example we’ll use something along
786 the following lines:</p>
788 <div class="listingblock">
789 <div class="content">
790 <pre class="highlight"><code>void f( variant<int, float> const& v )
792 if( int const * p = get_if<int>(&v) )
796 else if( float const * p = get_if<float>(&v) )
802 assert(false); // never happens
809 <h3 id="overview_visitation">Visitation</h3>
810 <div class="paragraph">
811 <p>Last but not least, there’s <code>visit</code>. <code>visit(f, v)</code> calls the a function object
812 <code>f</code> with the value contained in the <code>variant</code> <code>v</code> and returns the result. When
813 <code>v</code> is <code>variant<int, float></code>, it will call <code>f</code> with either an <code>int</code> or a
814 <code>float</code>. The function object must be prepared to accept both.</p>
816 <div class="paragraph">
817 <p>In practice, this can be achieved by having the function take a type that can
818 be passed either <code>int</code> or <code>float</code>, such as <code>double</code>:</p>
820 <div class="listingblock">
821 <div class="content">
822 <pre class="highlight"><code>double f( double x ) { return x; }
824 double g( variant<int, float> const& v )
826 return visit( f, v );
830 <div class="paragraph">
831 <p>By using a function object with an overloaded <code>operator()</code>:</p>
833 <div class="listingblock">
834 <div class="content">
835 <pre class="highlight"><code>struct F
837 void operator()(int x) const { /* use x */ }
838 void operator()(float x) const { /* use x */ }
841 void g( variant<int, float> const& v )
847 <div class="paragraph">
848 <p>Or by using a polymorphic lambda, as we did in our <code>Circle</code>/<code>Rectangle</code>
851 <div class="listingblock">
852 <div class="content">
853 <pre class="highlight"><code>void g( variant<int, float> const& v )
855 visit( [&]( auto const& x ){ std::cout << x << std::endl; }, v );
859 <div class="paragraph">
860 <p><code>visit</code> can also take more than one <code>variant</code>. <code>visit(f, v1, v2)</code> calls
861 <code>f(x1, x2)</code>, where <code>x1</code> is the value contained in <code>v1</code> and <code>x2</code> is the value
862 in <code>v2</code>.</p>
866 <h3 id="overview_default_construction">Default Construction</h3>
867 <div class="paragraph">
868 <p>The default constructor of <code>variant</code> value-initializes the first type in
869 the list. <code>variant<int, float>{}</code> holds <code>0</code> (of type <code>int</code>), and
870 <code>variant<float, int>{}</code> holds <code>0.0f</code>.</p>
872 <div class="paragraph">
873 <p>This is usually the desired behavior. However, in cases such as
874 <code>variant<std::mutex, std::recursive_mutex></code>, one might legitimately wish to
875 avoid constructing a <code>std::mutex</code> by default. A provided type, <code>monostate</code>,
876 can be used as the first type in those scenarios. <code>variant<monostate,
877 std::mutex, std::recursive_mutex></code> will default-construct a <code>monostate</code>,
878 which is basically a no-op, as <code>monostate</code> is effectively an empty <code>struct</code>.</p>
884 <h2 id="changelog">Revision History</h2>
885 <div class="sectionbody">
887 <h3 id="changelog_changes_in_1_71_0">Changes in 1.71.0</h3>
888 <div class="paragraph">
889 <p>After the Boost formal review, the implementation has been
890 changed to provide the strong exception safety guarantee,
891 instead of basic. <code>expected</code> has been removed.</p>
897 <h2 id="design">Design</h2>
898 <div class="sectionbody">
900 <h3 id="design_features">Features</h3>
901 <div class="paragraph">
902 <p>This <code>variant</code> implementation has two distinguishing features:</p>
907 <p>It’s never "valueless", that is, <code>variant<T1, T2, …​, Tn></code> has an
908 invariant that it always contains a valid value of one of the types
909 <code>T1</code>, <code>T2</code>, …​, <code>Tn</code>.</p>
912 <p>It provides the strong exception safety guarantee on assignment and
913 <code>emplace</code>.</p>
917 <div class="paragraph">
918 <p>This is achieved with the use of double storage, unless all of the
919 contained types have a non-throwing move constructor.</p>
923 <h3 id="design_rationale">Rationale</h3>
925 <h4 id="design_never_valueless">Never Valueless</h4>
926 <div class="paragraph">
927 <p>It makes intuitive sense that <code>variant<X, Y, Z></code> can hold only values
928 of type <code>X</code>, type <code>Y</code>, or type <code>Z</code>, and nothing else.</p>
930 <div class="paragraph">
931 <p>If we think of <code>variant</code> as an extension of <code>union</code>, since a <code>union</code>
932 has a state called "no active member", an argument can be made that a
933 <code>variant<X, Y, Z></code> should also have such an additional state, holding
934 none of <code>X</code>, <code>Y</code>, <code>Z</code>.</p>
936 <div class="paragraph">
937 <p>This however makes <code>variant</code> less convenient in practice and less useful
938 as a building block. If we really need a variable that only holds <code>X</code>,
939 <code>Y</code>, or <code>Z</code>, the additional empty state creates complications that need
940 to be worked around. And in the case where we do need this additional
941 empty state, we can just use <code>variant<empty, X, Y, Z></code>, with a suitable
942 <code>struct empty {};</code>.</p>
944 <div class="paragraph">
945 <p>From a pure design perspective, the case for no additional empty state is
946 solid. Implementation considerations, however, argue otherwise.</p>
948 <div class="paragraph">
949 <p>When we replace the current value of the <code>variant</code> (of, say, type <code>X</code>) with
950 another (of type <code>Y</code>), since the new value needs to occupy the same storage
951 as the old one, we need to destroy the old <code>X</code> first, then construct a new
952 <code>Y</code> in its place. But since this is C++, the construction can fail with an
953 exception. At this point the <code>variant</code> is in the "has no active member"
954 state that we’ve agreed it cannot be in.</p>
956 <div class="paragraph">
957 <p>This is a legitimate problem, and it is this problem that makes having
958 an empty/valueless state so appealing. We just leave the <code>variant</code> empty on
959 exception and we’re done.</p>
961 <div class="paragraph">
962 <p>As explained, though, this is undesirable from a design perspective as it
963 makes the component less useful and less elegant.</p>
965 <div class="paragraph">
966 <p>There are several ways around the issue. The most straightforward one is to
967 just disallow types whose construction can throw. Since we can always create
968 a temporary value first, then use the move constructor to initialize the one
969 in the <code>variant</code>, it’s enough to require a nonthrowing move constructor,
970 rather than all constructors to be nonthrowing.</p>
972 <div class="paragraph">
973 <p>Unfortunately, under at least one popular standard library implementation,
974 node based containers such as <code>std::list</code> and <code>std::map</code> have a potentially
975 throwing move constructor. Disallowing <code>variant<X, std::map<Y, Z>></code> is hardly
976 practical, so the exceptional case cannot be avoided.</p>
978 <div class="paragraph">
979 <p>On exception, we could also construct some other value, leaving the <code>variant</code>
980 valid; but in the general case, that construction can also throw. If one of
981 the types has a nonthrowing default constructor, we can use it; but if not,
984 <div class="paragraph">
985 <p>The approach Boost.Variant takes here is to allocate a temporary copy of
986 the value on the heap. On exception, a pointer to that temporary copy can be
987 stored into the <code>variant</code>. Pointer operations don’t throw.</p>
989 <div class="paragraph">
990 <p>Another option is to use double buffering. If our <code>variant</code> occupies twice
991 the storage, we can construct the new value in the unused half, then, once
992 the construction succeeds, destroy the old value in the other half.</p>
994 <div class="paragraph">
995 <p>When <code>std::variant</code> was standardized, none of those approaches was deemed
996 palatable, as all of them either introduce overhead or are too restrictive
997 with respect to the types a <code>variant</code> can contain. So as a compromise,
998 <code>std::variant</code> took a way that can (noncharitably) be described as "having
999 your cake and eating it too."</p>
1001 <div class="paragraph">
1002 <p>Since the described exceptional situation is relatively rare, <code>std::variant</code>
1003 has a special case, called "valueless", into which it goes on exception,
1004 but the interface acknowledges its existence as little as possible, allowing
1005 users to pretend that it doesn’t exist.</p>
1007 <div class="paragraph">
1008 <p>This is, arguably, not that bad from a practical point of view, but it leaves
1009 many of us wanting. Rare states that "never" occur are undertested and when
1010 that "never" actually happens, it’s usually in the most inconvenient of times.</p>
1012 <div class="paragraph">
1013 <p>This implementation does not follow <code>std::variant</code>; it statically guarantees
1014 that <code>variant</code> is never in a valueless state. The function
1015 <code>valueless_by_exception</code> is provided for compatibility, but it always returns
1016 <code>false</code>.</p>
1018 <div class="paragraph">
1019 <p>Instead, if the contained types are such that it’s not possible to avoid an
1020 exceptional situation when changing the contained value, double storage is
1025 <h4 id="design_strong_exception_safety">Strong Exception Safety</h4>
1026 <div class="paragraph">
1027 <p>The initial submission only provided the basic exception safety guarantee.
1028 If an attempt to change the contained value (via assignment or <code>emplace</code>)
1029 failed with an exception, and a type with a nonthrowing default constructor
1030 existed among the alternatives, a value of that type was created into the
1031 <code>variant</code>. The upside of this decision was that double storage was needed
1032 less frequently.</p>
1034 <div class="paragraph">
1035 <p>The reviewers were fairly united in hating it. Constructing a random type
1036 was deemed too unpredictable and not complying with the spirit of the
1037 basic guarantee. The default constructor of the chosen type, even if
1038 nonthrowing, may still have undesirable side effects. Or, if not that, a
1039 value of that type may have special significance for the surrounding code.
1040 Therefore, some argued, the <code>variant</code> should either remain with its
1041 old value, or transition into the new one, without synthesizing other
1044 <div class="paragraph">
1045 <p>At the other side of the spectrum, there were those who considered double
1046 storage unacceptable. But they considered it unacceptable in principle,
1047 regardless of the frequency with which it was used.</p>
1049 <div class="paragraph">
1050 <p>As a result, providing the strong exception safety guarantee on assignment
1051 and <code>emplace</code> was declared an acceptance condition.</p>
1053 <div class="paragraph">
1054 <p>In retrospect, this was the right decision. The reason the strong guarantee
1055 is generally not provided is because it doesn’t compose. When <code>X</code> and <code>Y</code>
1056 provide the basic guarantee on assignment, so does <code>struct { X x; Y y; };</code>.
1057 Similarly, when <code>X</code> and <code>Y</code> have nonthrowing assignments, so does the
1058 <code>struct</code>. But this doesn’t hold for the strong guarantee.</p>
1060 <div class="paragraph">
1061 <p>The usual practice is to provide the basic guarantee on assignment and
1062 let the user synthesize a "strong" assignment out of either a nonthrowing
1063 <code>swap</code> or a nonthrowing move assignment. That is, given <code>x1</code> and <code>x2</code> of
1064 type <code>X</code>, instead of the "basic" <code>x1 = x2;</code>, use either <code>X(x2).swap(x1);</code>
1065 or <code>x1 = X(x2);</code>.</p>
1067 <div class="paragraph">
1068 <p>Nearly all types provide a nonthrowing <code>swap</code> or a nonthrowing move
1069 assignment, so this works well. Nearly all, except <code>variant</code>, which in the
1070 general case has neither a nonthrowing <code>swap</code> nor a nonthrowing move
1071 assignment. If <code>variant</code> does not provide the strong guarantee itself, it’s
1072 impossible for the user to synthesize it.</p>
1074 <div class="paragraph">
1075 <p>So it should, and so it does.</p>
1080 <h3 id="design_differences_with_stdvariant">Differences with std::variant</h3>
1081 <div class="paragraph">
1082 <p>The main differences between this implementation and <code>std::variant</code> are:</p>
1087 <p>No valueless-by-exception state: <code>valueless_by_exception()</code> always
1088 returns <code>false</code>.</p>
1091 <p>Strong exception safety guarantee on assignment and <code>emplace</code>.</p>
1094 <p><code>emplace</code> first constructs the new value and then destroys the old one;
1095 in the single storage case, this translates to constructing a temporary
1096 and then moving it into place.</p>
1099 <p>A converting constructor from, e.g. <code>variant<int, float></code> to
1100 <code>variant<float, double, int></code> is provided as an extension.</p>
1103 <p>The reverse operation, going from <code>variant<float, double, int></code> to
1104 <code>variant<int, float></code> is provided as the member function <code>subset<U…​></code>.
1105 (This operation can throw if the current state of the variant cannot be
1109 <p><code>variant<T…​></code> is not (yet) trivial when all contained types are trivial,
1110 as mandated by C++17.</p>
1113 <p>The C++20 additions and changes to <code>std::variant</code> have not yet been
1120 <h3 id="design_differences_with_boost_variant">Differences with Boost.Variant</h3>
1121 <div class="paragraph">
1122 <p>This library is API compatible with <code>std::variant</code>. As such, its interface
1123 is different from Boost.Variant’s. For example, visitation is performed via
1124 <code>visit</code> instead of <code>apply_visitor</code>.</p>
1126 <div class="paragraph">
1127 <p>Recursive variants are not supported.</p>
1129 <div class="paragraph">
1130 <p>Double storage is used instead of temporary heap backup. This <code>variant</code> is
1131 always "stack-based", it never allocates, and never throws <code>bad_alloc</code> on
1138 <h2 id="implementation">Implementation</h2>
1139 <div class="sectionbody">
1141 <h3 id="implementation_dependencies">Dependencies</h3>
1142 <div class="paragraph">
1143 <p>This implementation only depends on Boost.Config and Boost.Mp11.</p>
1147 <h3 id="implementation_supported_compilers">Supported Compilers</h3>
1151 <p>GCC 4.8 or later with <code>-std=c++11</code> or above</p>
1154 <p>Clang 3.5 or later with <code>-std=c++11</code> or above</p>
1157 <p>Visual Studio 2015, 2017, 2019</p>
1161 <div class="paragraph">
1162 <p>Tested on <a href="https://travis-ci.org/boostorg/variant2/">Travis</a> and
1163 <a href="https://ci.appveyor.com/project/pdimov/variant2-fkab9">Appveyor</a>.</p>
1169 <h2 id="reference">Reference</h2>
1170 <div class="sectionbody">
1172 <h3 id="ref_boostvariant2variant_hpp"><boost/variant2/variant.hpp></h3>
1174 <h4 id="ref_synopsis">Synopsis</h4>
1175 <div class="listingblock">
1176 <div class="content">
1177 <pre class="highlight"><code>namespace boost {
1178 namespace variant2 {
1182 template<class T> struct in_place_type_t {};
1183 template<class T> constexpr in_place_type_t<T> in_place_type{};
1187 template<std::size_t I> struct in_place_index_t {};
1188 template<std::size_t I> constexpr in_place_index_t<I> in_place_index{};
1192 template<class... T> class variant;
1196 template<class T> struct variant_size {};
1198 template<class T> struct variant_size<T const>: variant_size<T> {};
1199 template<class T> struct variant_size<T volatile>: variant_size<T> {};
1200 template<class T> struct variant_size<T const volatile>: variant_size<T> {};
1202 template<class T> struct variant_size<T&>: variant_size<T> {}; // extension
1203 template<class T> struct variant_size<T&&>: variant_size<T> {}; // extension
1205 template<class T>
1206 inline constexpr size_t variant_size_v = variant_size<T>::value;
1208 template<class... T>
1209 struct variant_size<variant<T...>>:
1210 std::integral_constant<std::size_t, sizeof...(T)> {};
1212 // variant_alternative
1214 template<size_t I, class T> struct variant_alternative {};
1216 template<size_t I, class T> struct variant_alternative<I, T const>;
1217 template<size_t I, class T> struct variant_alternative<I, T volatile>;
1218 template<size_t I, class T> struct variant_alternative<I, T const volatile>;
1220 template<size_t I, class T> struct variant_alternative<I, T&>; // extension
1221 template<size_t I, class T> struct variant_alternative<I, T&&>; // extension
1223 template<size_t I, class T>
1224 using variant_alternative_t = typename variant_alternative<I, T>::type;
1226 template<size_t I, class... T>
1227 struct variant_alternative<I, variant<T...>>;
1231 constexpr std::size_t variant_npos = -1;
1233 // holds_alternative
1235 template<class U, class... T>
1236 constexpr bool holds_alternative(const variant<T...>& v) noexcept;
1240 template<size_t I, class... T>
1241 constexpr variant_alternative_t<I, variant<T...>>&
1242 get(variant<T...>& v);
1243 template<size_t I, class... T>
1244 constexpr variant_alternative_t<I, variant<T...>>&&
1245 get(variant<T...>&& v);
1246 template<size_t I, class... T>
1247 constexpr const variant_alternative_t<I, variant<T...>>&
1248 get(const variant<T...>& v);
1249 template<size_t I, class... T>
1250 constexpr const variant_alternative_t<I, variant<T...>>&&
1251 get(const variant<T...>&& v);
1253 template<class U, class... T>
1254 constexpr U& get(variant<T...>& v);
1255 template<class U, class... T>
1256 constexpr U&& get(variant<T...>&& v);
1257 template<class U, class... T>
1258 constexpr const U& get(const variant<T...>& v);
1259 template<class U, class... T>
1260 constexpr const U&& get(const variant<T...>&& v);
1264 template<size_t I, class... T>
1265 constexpr add_pointer_t<variant_alternative_t<I, variant<T...>>>
1266 get_if(variant<T...>* v) noexcept;
1267 template<size_t I, class... T>
1268 constexpr add_pointer_t<const variant_alternative_t<I, variant<T...>>>
1269 get_if(const variant<T...>* v) noexcept;
1271 template<class U, class... T>
1272 constexpr add_pointer_t<U>
1273 get_if(variant<T...>* v) noexcept;
1274 template<class U, class... T>
1275 constexpr add_pointer_t<const U>
1276 get_if(const variant<T...>* v) noexcept;
1278 // relational operators
1280 template<class... T>
1281 constexpr bool operator==(const variant<T...>& v, const variant<T...>& w);
1282 template<class... T>
1283 constexpr bool operator!=(const variant<T...>& v, const variant<T...>& w);
1284 template<class... T>
1285 constexpr bool operator<(const variant<T...>& v, const variant<T...>& w);
1286 template<class... T>
1287 constexpr bool operator>(const variant<T...>& v, const variant<T...>& w);
1288 template<class... T>
1289 constexpr bool operator<=(const variant<T...>& v, const variant<T...>& w);
1290 template<class... T>
1291 constexpr bool operator>=(const variant<T...>& v, const variant<T...>& w);
1295 template<class F, class... V>
1296 constexpr /*see below*/ visit(F&& f, V&&... v);
1300 struct monostate {};
1302 constexpr bool operator==(monostate, monostate) noexcept { return true; }
1303 constexpr bool operator!=(monostate, monostate) noexcept { return false; }
1304 constexpr bool operator<(monostate, monostate) noexcept { return false; }
1305 constexpr bool operator>(monostate, monostate) noexcept { return false; }
1306 constexpr bool operator<=(monostate, monostate) noexcept { return true; }
1307 constexpr bool operator>=(monostate, monostate) noexcept { return true; }
1311 template<class... T>
1312 void swap(variant<T...>& v, variant<T...>& w) noexcept( /*see below*/ );
1314 // bad_variant_access
1316 class bad_variant_access;
1318 } // namespace variant2
1319 } // namespace boost</code></pre>
1324 <h4 id="ref_variant">variant</h4>
1325 <div class="listingblock">
1326 <div class="content">
1327 <pre class="highlight"><code>namespace boost {
1328 namespace variant2 {
1330 template<class... T> class variant
1336 constexpr variant() noexcept( /*see below*/ );
1338 constexpr variant( variant const & r ) noexcept( /*see below*/ );
1339 constexpr variant( variant&& r ) noexcept( /*see below*/ );
1341 template<class U>
1342 constexpr variant( U&& u ) noexcept( /*see below*/ );
1344 template<class U, class... A>
1345 constexpr explicit variant( in_place_type_t<U>, A&&... a );
1346 template<class U, class V, class... A>
1347 constexpr explicit variant( in_place_type_t<U>,
1348 std::initializer_list<V> il, A&&... a );
1350 template<size_t I, class... A>
1351 constexpr explicit variant( in_place_index_t<I>, A&&... a );
1352 template<size_t I, class V, class... A>
1353 constexpr explicit variant( in_place_index_t<I>,
1354 std::initializer_list<V> il, A&&... a );
1362 constexpr variant& operator=( variant const & r ) noexcept( /*see below*/ );
1363 constexpr variant& operator=( variant&& r ) noexcept( /*see below*/ );
1365 template<class U> constexpr variant& operator=( U&& u ) noexcept( /*see below*/ );
1369 template<class U, class... A>
1370 constexpr U& emplace( A&&... a );
1371 template<class U, class V, class... A>
1372 constexpr U& emplace( std::initializer_list<V> il, A&&... a );
1374 template<size_t I, class... A>
1375 constexpr variant_alternative_t<I, variant<T...>>&
1376 emplace( A&&... a );
1377 template<size_t I, class V, class... A>
1378 constexpr variant_alternative_t<I, variant<T...>>&
1379 emplace( std::initializer_list<V> il, A&&... a );
1383 constexpr bool valueless_by_exception() const noexcept;
1384 constexpr size_t index() const noexcept;
1388 void swap( variant& r ) noexcept( /*see below*/ );
1390 // converting constructors (extension)
1392 template<class... U> variant( variant<U...> const& r )
1393 noexcept( /*see below*/ );
1395 template<class... U> variant( variant<U...>&& r )
1396 noexcept( /*see below*/ );
1398 // subset (extension)
1400 template<class... U> constexpr variant<U...> subset() & ;
1401 template<class... U> constexpr variant<U...> subset() && ;
1402 template<class... U> constexpr variant<U...> subset() const& ;
1403 template<class... U> constexpr variant<U...> subset() const&& ;
1406 } // namespace variant2
1407 } // namespace boost</code></pre>
1410 <div class="paragraph">
1411 <p>In the descriptions that follow, let <code>i</code> be in the range <code>[0, sizeof…​(T))</code>,
1412 and <code>Ti</code> be the <code>i</code>-th type in <code>T…​</code>.</p>
1415 <h5 id="ref_constructors">Constructors</h5>
1416 <div class="listingblock">
1417 <div class="content">
1418 <pre class="highlight"><code>constexpr variant() noexcept( std::is_nothrow_default_constructible_v<T0> );</code></pre>
1421 <div class="ulist none">
1427 <dt class="hdlist1">Effects: </dt>
1429 <p>Constructs a <code>variant</code> holding a value-initialized value of
1430 type <code>T0</code>.</p>
1432 <dt class="hdlist1">Ensures: </dt>
1434 <p><code>index() == 0</code>.</p>
1436 <dt class="hdlist1">Throws: </dt>
1438 <p>Any exception thrown by the value-initialization of <code>T0</code>.</p>
1440 <dt class="hdlist1">Remarks: </dt>
1442 <p>This function does not participate in overload resolution unless
1443 <code>std::is_default_constructible_v<T0></code> is <code>true</code>.</p>
1450 <div class="listingblock">
1451 <div class="content">
1452 <pre class="highlight"><code>constexpr variant( variant const & w )
1453 noexcept( mp_all<std::is_nothrow_copy_constructible<T>...>::value );</code></pre>
1456 <div class="ulist none">
1462 <dt class="hdlist1">Effects: </dt>
1464 <p>Initializes the variant to hold the same alternative and value as
1467 <dt class="hdlist1">Throws: </dt>
1469 <p>Any exception thrown by the initialization of the contained value.</p>
1471 <dt class="hdlist1">Remarks: </dt>
1473 <p>This function does not participate in overload resolution unless
1474 <code>std::is_copy_constructible_v<Ti></code> is <code>true</code> for all <code>i</code>.</p>
1481 <div class="listingblock">
1482 <div class="content">
1483 <pre class="highlight"><code>constexpr variant( variant&& w )
1484 noexcept( mp_all<std::is_nothrow_move_constructible<T>...>::value );</code></pre>
1487 <div class="ulist none">
1493 <dt class="hdlist1">Effects: </dt>
1495 <p>Initializes the variant to hold the same alternative and value as
1498 <dt class="hdlist1">Throws: </dt>
1500 <p>Any exception thrown by the move-initialization of the contained
1503 <dt class="hdlist1">Remarks: </dt>
1505 <p>This function does not participate in overload resolution unless
1506 <code>std::is_move_constructible_v<Ti></code> is <code>true</code> for all <code>i</code>.</p>
1513 <div class="listingblock">
1514 <div class="content">
1515 <pre class="highlight"><code>template<class U> constexpr variant( U&& u ) noexcept(/*see below*/);</code></pre>
1518 <div class="ulist none">
1522 <div class="paragraph">
1523 <p>Let <code>Tj</code> be a type that is determined as follows: build an imaginary function
1524 <code>FUN(Ti)</code> for each alternative type <code>Ti</code>. The overload <code>FUN(Tj)</code> selected by
1525 overload resolution for the expression <code>FUN(std::forward<U>(u))</code> defines the
1526 alternative <code>Tj</code> which is the type of the contained value after construction.</p>
1530 <dt class="hdlist1">Effects: </dt>
1532 <p>Initializes <code>*this</code> to hold the alternative type <code>Tj</code> and
1533 initializes the contained value from <code>std::forward<U>(u)</code>.</p>
1535 <dt class="hdlist1">Ensures: </dt>
1537 <p><code>holds_alternative<Tj>(*this)</code>.</p>
1539 <dt class="hdlist1">Throws: </dt>
1541 <p>Any exception thrown by the initialization of the contained value.</p>
1543 <dt class="hdlist1">Remarks: </dt>
1545 <p>The expression inside <code>noexcept</code> is equivalent to
1546 <code>std::is_nothrow_constructible_v<Tj, U></code>. This function does not participate in
1547 overload resolution unless</p>
1551 <p><code>sizeof…​(T)</code> is nonzero,</p>
1554 <p><code>std::is_same_v<std::remove_cvref_t<U>, variant></code> is <code>false</code>,</p>
1557 <p><code>std::remove_cvref_t<U></code> is neither a specialization of <code>in_place_type_t</code> nor a
1558 specialization of <code>in_place_index_t</code>,</p>
1561 <p><code>std::is_constructible_v<Tj, U></code> is <code>true</code>, and</p>
1564 <p>the expression <code>FUN(std::forward<U>(u))</code> is well-formed.</p>
1574 <div class="listingblock">
1575 <div class="content">
1576 <pre class="highlight"><code>template<class U, class... A>
1577 constexpr explicit variant( in_place_type_t<U>, A&&... a );</code></pre>
1580 <div class="ulist none">
1586 <dt class="hdlist1">Effects: </dt>
1588 <p>Initializes the contained value of type <code>U</code> with the arguments
1589 <code>std::forward<A>(a)…​</code>.</p>
1591 <dt class="hdlist1">Ensures: </dt>
1593 <p><code>holds_alternative<U>(*this)</code>.</p>
1595 <dt class="hdlist1">Throws: </dt>
1597 <p>Any exception thrown by the initialization of the contained value.</p>
1599 <dt class="hdlist1">Remarks: </dt>
1601 <p>This function does not participate in overload resolution unless
1602 there is exactly one occurrence of <code>U</code> in <code>T…​</code> and
1603 <code>std::is_constructible_v<U, A…​></code> is true.</p>
1610 <div class="listingblock">
1611 <div class="content">
1612 <pre class="highlight"><code>template<class U, class V, class... A>
1613 constexpr explicit variant( in_place_type_t<U>, std::initializer_list<V> il,
1614 A&&... a );</code></pre>
1617 <div class="ulist none">
1623 <dt class="hdlist1">Effects: </dt>
1625 <p>Initializes the contained value of type <code>U</code> with the arguments <code>il</code>,
1626 <code>std::forward<A>(a)…​</code>.</p>
1628 <dt class="hdlist1">Ensures: </dt>
1630 <p><code>holds_alternative<U>(*this)</code>.</p>
1632 <dt class="hdlist1">Throws: </dt>
1634 <p>Any exception thrown by the initialization of the contained value.</p>
1636 <dt class="hdlist1">Remarks: </dt>
1638 <p>This function does not participate in overload resolution unless
1639 there is exactly one occurrence of <code>U</code> in <code>T…​</code> and
1640 <code>std::is_constructible_v<U, initializer_list<V>&, A…​></code> is <code>true</code>.</p>
1647 <div class="listingblock">
1648 <div class="content">
1649 <pre class="highlight"><code>template<size_t I, class... A>
1650 constexpr explicit variant( in_place_index_t<I>, A&&... a );</code></pre>
1653 <div class="ulist none">
1659 <dt class="hdlist1">Effects: </dt>
1661 <p>Initializes the contained value of type <code>TI</code> with the arguments
1662 <code>std::forward<A>(a)…​</code>.</p>
1664 <dt class="hdlist1">Ensures: </dt>
1666 <p><code>index() == I</code>.</p>
1668 <dt class="hdlist1">Throws: </dt>
1670 <p>Any exception thrown by the initialization of the contained value.</p>
1672 <dt class="hdlist1">Remarks: </dt>
1674 <p>This function does not participate in overload resolution unless
1675 <code>I < sizeof…​(T)</code> and <code>std::is_constructible_v<TI, A…​></code> is <code>true</code>.</p>
1682 <div class="listingblock">
1683 <div class="content">
1684 <pre class="highlight"><code>template<size_t I, class V, class... A>
1685 constexpr explicit variant( in_place_index_t<I>, std::initializer_list<V> il,
1686 A&&... a );</code></pre>
1689 <div class="ulist none">
1695 <dt class="hdlist1">Effects: </dt>
1697 <p>Initializes the contained value of type <code>TI</code> with the arguments
1698 <code>il</code>, <code>std::forward<A>(a)…​</code>.</p>
1700 <dt class="hdlist1">Ensures: </dt>
1702 <p><code>index() == I</code>.</p>
1704 <dt class="hdlist1">Throws: </dt>
1706 <p>Any exception thrown by the initialization of the contained value.</p>
1708 <dt class="hdlist1">Remarks: </dt>
1710 <p>This function does not participate in overload resolution unless
1711 <code>I < sizeof…​(T)</code> and
1712 <code>std::is_constructible_v<TI, initializer_list<V>&, A…​></code> is <code>true</code>.</p>
1721 <h5 id="ref_destructor">Destructor</h5>
1722 <div class="listingblock">
1723 <div class="content">
1724 <pre class="highlight"><code>~variant();</code></pre>
1727 <div class="ulist none">
1733 <dt class="hdlist1">Effects: </dt>
1735 <p>Destroys the currently contained value.</p>
1744 <h5 id="ref_assignment">Assignment</h5>
1745 <div class="listingblock">
1746 <div class="content">
1747 <pre class="highlight"><code>constexpr variant& operator=( const variant& r )
1748 noexcept( mp_all<std::is_nothrow_copy_constructible<T>...>::value );</code></pre>
1751 <div class="ulist none">
1755 <div class="paragraph">
1756 <p>Let <code>j</code> be <code>r.index()</code>.</p>
1760 <dt class="hdlist1">Effects: </dt>
1762 <p><code>emplace<j>(get<j>(r))</code>.</p>
1764 <dt class="hdlist1">Returns: </dt>
1766 <p><code>*this</code>.</p>
1768 <dt class="hdlist1">Ensures: </dt>
1770 <p><code>index() == r.index()</code>.</p>
1772 <dt class="hdlist1">Remarks: </dt>
1774 <p>This operator does not participate in overload resolution unless
1775 <code>std::is_copy_constructible_v<Ti> && std::is_copy_assignable_v<Ti></code> is
1776 <code>true</code> for all <code>i</code>.</p>
1783 <div class="listingblock">
1784 <div class="content">
1785 <pre class="highlight"><code>constexpr variant& operator=( variant&& r )
1786 noexcept( mp_all<std::is_nothrow_move_constructible<T>...>::value );</code></pre>
1789 <div class="ulist none">
1793 <div class="paragraph">
1794 <p>Let <code>j</code> be <code>r.index()</code>.</p>
1798 <dt class="hdlist1">Effects: </dt>
1800 <p><code>emplace<j>(get<j>(std::move(r)))</code>.</p>
1802 <dt class="hdlist1">Returns: </dt>
1804 <p><code>*this</code>.</p>
1806 <dt class="hdlist1">Ensures: </dt>
1808 <p><code>index() == r.index()</code>.</p>
1810 <dt class="hdlist1">Remarks: </dt>
1812 <p>This operator does not participate in overload resolution unless
1813 <code>std::is_move_constructible_v<Ti> && std::is_move_assignable_v<Ti></code> is
1814 <code>true</code> for all <code>i</code>.</p>
1821 <div class="listingblock">
1822 <div class="content">
1823 <pre class="highlight"><code>template<class U> constexpr variant& operator=( U&& u )
1824 noexcept( /*see below*/ );</code></pre>
1827 <div class="ulist none">
1831 <div class="paragraph">
1832 <p>Let <code>Tj</code> be a type that is determined as follows: build an imaginary function
1833 <code>FUN(Ti)</code> for each alternative type <code>Ti</code>. The overload <code>FUN(Tj)</code> selected by
1834 overload resolution for the expression <code>FUN(std::forward<U>(u))</code> defines the
1835 alternative <code>Tj</code> which is the type of the contained value after construction.</p>
1839 <dt class="hdlist1">Effects: </dt>
1841 <p><code>emplace<j>(std::forward<U>(u))</code>.</p>
1843 <dt class="hdlist1">Returns: </dt>
1845 <p><code>*this</code>.</p>
1847 <dt class="hdlist1">Ensures: </dt>
1849 <p><code>index() == j</code>.</p>
1851 <dt class="hdlist1">Remarks: </dt>
1853 <p>The expression inside <code>noexcept</code> is <code>std::is_nothrow_constructible_v<Tj, U&&></code>.
1854 This operator does not participate in overload resolution unless</p>
1858 <p><code>std::is_same_v<std::remove_cvref_t<T>, variant></code> is <code>false</code>,</p>
1861 <p><code>std::is_constructible_v<Tj, U&&> && std::is_assignable_v<Tj&, U&&></code> is
1862 <code>true</code>, and</p>
1865 <p>the expression <code>FUN(std::forward<U>(u))</code> (with <code>FUN</code> being the
1866 above-mentioned set of imaginary functions) is well-formed.</p>
1878 <h5 id="ref_modifiers">Modifiers</h5>
1879 <div class="listingblock">
1880 <div class="content">
1881 <pre class="highlight"><code>template<class U, class... A>
1882 constexpr U& emplace( A&&... a );</code></pre>
1885 <div class="ulist none">
1889 <div class="paragraph">
1890 <p>Let <code>I</code> be the zero-based index of <code>U</code> in <code>T…​</code>.</p>
1894 <dt class="hdlist1">Effects: </dt>
1896 <p>Equivalent to: <code>return emplace<I>(std::forward<A>(a)…​);</code></p>
1898 <dt class="hdlist1">Remarks: </dt>
1900 <p>This function shall not participate in overload resolution unless
1901 <code>std::is_constructible_v<U, A&&…​></code> is <code>true</code> and <code>U</code> occurs exactly once
1902 in <code>T…​</code>.</p>
1909 <div class="listingblock">
1910 <div class="content">
1911 <pre class="highlight"><code>template<class U, class V, class... A>
1912 constexpr U& emplace( std::initializer_list<V> il, A&&... a );</code></pre>
1915 <div class="ulist none">
1919 <div class="paragraph">
1920 <p>Let <code>I</code> be the zero-based index of <code>U</code> in <code>T…​</code>.</p>
1924 <dt class="hdlist1">Effects: </dt>
1926 <p>Equivalent to: <code>return emplace<I>(il, std::forward<A>(a)…​);</code></p>
1928 <dt class="hdlist1">Remarks: </dt>
1930 <p>This function shall not participate in overload resolution unless
1931 <code>std::is_constructible_v<U, std::initializer_list<V>&, A&&…​></code> is <code>true</code>
1932 and <code>U</code> occurs exactly once in <code>T…​</code>.</p>
1939 <div class="listingblock">
1940 <div class="content">
1941 <pre class="highlight"><code>template<size_t I, class... A>
1942 constexpr variant_alternative_t<I, variant<T...>>&
1943 emplace( A&&... a );</code></pre>
1946 <div class="ulist none">
1952 <dt class="hdlist1">Requires: </dt>
1954 <p><code>I < sizeof…​(T)</code>.</p>
1956 <dt class="hdlist1">Effects: </dt>
1958 <p>Destroys the currently contained value, then initializes a new contained
1959 value as if using the expression <code>Ti(std::forward<A>(a)…​)</code>.</p>
1961 <dt class="hdlist1">Ensures: </dt>
1963 <p><code>index() == I</code>.</p>
1965 <dt class="hdlist1">Returns: </dt>
1967 <p>A reference to the new contained value.</p>
1969 <dt class="hdlist1">Throws: </dt>
1971 <p>Nothing unless the initialization of the new contained value throws.</p>
1973 <dt class="hdlist1">Exception Safety: </dt>
1975 <p>Strong. On exception, the contained value is unchanged.</p>
1977 <dt class="hdlist1">Remarks: </dt>
1979 <p>This function shall not participate in overload resolution unless
1980 <code>std::is_constructible_v<Ti, A&&…​></code> is <code>true</code>.</p>
1987 <div class="listingblock">
1988 <div class="content">
1989 <pre class="highlight"><code>template<size_t I, class V, class... A>
1990 constexpr variant_alternative_t<I, variant<T...>>&
1991 emplace( std::initializer_list<V> il, A&&... a );</code></pre>
1994 <div class="ulist none">
2000 <dt class="hdlist1">Requires: </dt>
2002 <p><code>I < sizeof…​(T)</code>.</p>
2004 <dt class="hdlist1">Effects: </dt>
2006 <p>Destroys the currently contained value, then initializes a new contained
2007 value as if using the expression <code>Ti(il, std::forward<A>(a)…​)</code>.</p>
2009 <dt class="hdlist1">Ensures: </dt>
2011 <p><code>index() == I</code>.</p>
2013 <dt class="hdlist1">Returns: </dt>
2015 <p>A reference to the new contained value.</p>
2017 <dt class="hdlist1">Throws: </dt>
2019 <p>Nothing unless the initialization of the new contained value throws.</p>
2021 <dt class="hdlist1">Exception Safety: </dt>
2023 <p>Strong. On exception, the contained value is unchanged.</p>
2025 <dt class="hdlist1">Remarks: </dt>
2027 <p>This function shall not participate in overload resolution unless
2028 <code>std::is_constructible_v<Ti, std::initializer_list<V>&, A&&…​></code> is <code>true</code>.</p>
2037 <h5 id="ref_value_status">Value Status</h5>
2038 <div class="listingblock">
2039 <div class="content">
2040 <pre class="highlight"><code>constexpr bool valueless_by_exception() const noexcept;</code></pre>
2043 <div class="ulist none">
2049 <dt class="hdlist1">Returns: </dt>
2051 <p><code>false</code>.</p>
2058 <div class="admonitionblock note">
2062 <div class="title">Note</div>
2064 <td class="content">
2065 This function is provided purely for compatibility with <code>std::variant</code>.
2070 <div class="listingblock">
2071 <div class="content">
2072 <pre class="highlight"><code>constexpr size_t index() const noexcept;</code></pre>
2075 <div class="ulist none">
2081 <dt class="hdlist1">Returns: </dt>
2083 <p>The zero-based index of the active alternative.</p>
2092 <h5 id="ref_swap">Swap</h5>
2093 <div class="listingblock">
2094 <div class="content">
2095 <pre class="highlight"><code>void swap( variant& r ) noexcept( mp_all<std::is_nothrow_move_constructible<T>...,
2096 is_nothrow_swappable<T>...>::value );</code></pre>
2099 <div class="ulist none">
2105 <dt class="hdlist1">Effects: </dt>
2110 <p>If <code>index() == r.index()</code>, calls <code>swap(get<I>(*this), get<I>(r))</code>,
2111 where <code>I</code> is <code>index()</code>.</p>
2115 <code>variant tmp(std::move(*this)); *this = std::move(r); r = std::move(tmp);</code></p>
2127 <h5 id="ref_converting_constructors_extension">Converting Constructors (extension)</h5>
2128 <div class="listingblock">
2129 <div class="content">
2130 <pre class="highlight"><code>template<class... U> variant( variant<U...> const& r )
2131 noexcept( mp_all<std::is_nothrow_copy_constructible<U>...>::value );</code></pre>
2134 <div class="ulist none">
2140 <dt class="hdlist1">Effects: </dt>
2142 <p>Initializes the contained value from the contained value of <code>r</code>.</p>
2144 <dt class="hdlist1">Throws: </dt>
2146 <p>Any exception thrown by the initialization of the contained value.</p>
2148 <dt class="hdlist1">Remarks: </dt>
2150 <p>This function does not participate in overload resolution unless
2151 all types in <code>U…​</code> are in <code>T…​</code> and
2152 <code>std::is_copy_constructible_v<Ui>::value</code> is <code>true</code> for all <code>Ui</code>.</p>
2159 <div class="listingblock">
2160 <div class="content">
2161 <pre class="highlight"><code>template<class... U> variant( variant<U...>&& r )
2162 noexcept( mp_all<std::is_nothrow_move_constructible<U>...>::value );</code></pre>
2165 <div class="ulist none">
2171 <dt class="hdlist1">Effects: </dt>
2173 <p>Initializes the contained value from the contained value of
2174 <code>std::move(r)</code>.</p>
2176 <dt class="hdlist1">Throws: </dt>
2178 <p>Any exception thrown by the initialization of the contained value.</p>
2180 <dt class="hdlist1">Remarks: </dt>
2182 <p>This function does not participate in overload resolution unless
2183 all types in <code>U…​</code> are in <code>T…​</code> and
2184 <code>std::is_move_constructible_v<Ui>::value</code> is <code>true</code> for all <code>Ui</code>.</p>
2193 <h5 id="ref_subset_extension">Subset (extension)</h5>
2194 <div class="listingblock">
2195 <div class="content">
2196 <pre class="highlight"><code>template<class... U> constexpr variant<U...> subset() & ;</code></pre>
2199 <div class="listingblock">
2200 <div class="content">
2201 <pre class="highlight"><code>template<class... U> constexpr variant<U...> subset() const& ;</code></pre>
2204 <div class="ulist none">
2210 <dt class="hdlist1">Returns: </dt>
2212 <p>A <code>variant<U…​></code> whose contained value is copy-initialized from
2213 the contained value of <code>*this</code> and has the same type.</p>
2215 <dt class="hdlist1">Throws: </dt>
2220 <p>If the active alternative of <code>*this</code> is not among the types in <code>U…​</code>,
2221 <code>bad_variant_access</code>.</p>
2224 <p>Otherwise, any exception thrown by the initialization of the contained value.</p>
2229 <dt class="hdlist1">Remarks: </dt>
2231 <p>This function does not participate in overload resolution unless
2232 all types in <code>U…​</code> are in <code>T…​</code> and
2233 <code>std::is_copy_constructible_v<Ui>::value</code> is <code>true</code> for all <code>Ui</code>.</p>
2240 <div class="listingblock">
2241 <div class="content">
2242 <pre class="highlight"><code>template<class... U> constexpr variant<U...> subset() && ;</code></pre>
2245 <div class="listingblock">
2246 <div class="content">
2247 <pre class="highlight"><code>template<class... U> constexpr variant<U...> subset() const&& ;</code></pre>
2250 <div class="ulist none">
2256 <dt class="hdlist1">Returns: </dt>
2258 <p>A <code>variant<U…​></code> whose contained value is move-initialized from
2259 the contained value of <code>*this</code> and has the same type.</p>
2261 <dt class="hdlist1">Throws: </dt>
2266 <p>If the active alternative of <code>*this</code> is not among the types in <code>U…​</code>,
2267 <code>bad_variant_access</code>.</p>
2270 <p>Otherwise, any exception thrown by the initialization of the contained value.</p>
2275 <dt class="hdlist1">Remarks: </dt>
2277 <p>This function does not participate in overload resolution unless
2278 all types in <code>U…​</code> are in <code>T…​</code> and
2279 <code>std::is_move_constructible_v<Ui>::value</code> is <code>true</code> for all <code>Ui</code>.</p>
2289 <h4 id="ref_variant_alternative">variant_alternative</h4>
2290 <div class="listingblock">
2291 <div class="content">
2292 <pre class="highlight"><code>template<size_t I, class T> struct variant_alternative<I, T const>;</code></pre>
2295 <div class="listingblock">
2296 <div class="content">
2297 <pre class="highlight"><code>template<size_t I, class T> struct variant_alternative<I, T volatile>;</code></pre>
2300 <div class="listingblock">
2301 <div class="content">
2302 <pre class="highlight"><code>template<size_t I, class T> struct variant_alternative<I, T const volatile>;</code></pre>
2305 <div class="listingblock">
2306 <div class="content">
2307 <pre class="highlight"><code>template<size_t I, class T> struct variant_alternative<I, T&>; // extension</code></pre>
2310 <div class="listingblock">
2311 <div class="content">
2312 <pre class="highlight"><code>template<size_t I, class T> struct variant_alternative<I, T&&>; // extension</code></pre>
2315 <div class="ulist none">
2319 <div class="openblock">
2320 <div class="content">
2321 <div class="paragraph">
2322 <p>If <code>typename variant_alternative<I, T>::type</code> exists and is <code>U</code>,</p>
2327 <p><code>variant_alternative<I, T const>::type</code> is <code>U const</code>;</p>
2330 <p><code>variant_alternative<I, T volatile>::type</code> is <code>U volatile</code>;</p>
2333 <p><code>variant_alternative<I, T const volatile>::type</code> is <code>U const volatile</code>.</p>
2336 <p><code>variant_alternative<I, T&>::type</code> is <code>U&</code>.</p>
2339 <p><code>variant_alternative<I, T&&>::type</code> is <code>U&&</code>.</p>
2343 <div class="paragraph">
2344 <p>Otherwise, these structs have no member <code>type</code>.</p>
2351 <div class="listingblock">
2352 <div class="content">
2353 <pre class="highlight"><code>template<size_t I, class... T>
2354 struct variant_alternative<I, variant<T...>>;</code></pre>
2357 <div class="ulist none">
2361 <div class="paragraph">
2362 <p>When <code>I < sizeof…​(T)</code>, the nested type <code>type</code> is an alias for the <code>I</code>-th
2363 (zero-based) type in <code>T…​</code>. Otherwise, there is no member <code>type</code>.</p>
2370 <h4 id="ref_holds_alternative">holds_alternative</h4>
2371 <div class="listingblock">
2372 <div class="content">
2373 <pre class="highlight"><code>template<class U, class... T>
2374 constexpr bool holds_alternative(const variant<T...>& v) noexcept;</code></pre>
2377 <div class="ulist none">
2383 <dt class="hdlist1">Requires: </dt>
2385 <p>The type <code>U</code> occurs exactly once in <code>T…​</code>. Otherwise, the
2386 program is ill-formed.</p>
2388 <dt class="hdlist1">Returns: </dt>
2390 <p><code>true</code> if <code>index()</code> is equal to the zero-based index of <code>U</code>
2391 in <code>T…​</code>.</p>
2400 <h4 id="ref_get">get</h4>
2401 <div class="listingblock">
2402 <div class="content">
2403 <pre class="highlight"><code>template<size_t I, class... T>
2404 constexpr variant_alternative_t<I, variant<T...>>&
2405 get(variant<T...>& v);</code></pre>
2408 <div class="listingblock">
2409 <div class="content">
2410 <pre class="highlight"><code>template<size_t I, class... T>
2411 constexpr variant_alternative_t<I, variant<T...>>&&
2412 get(variant<T...>&& v);</code></pre>
2415 <div class="listingblock">
2416 <div class="content">
2417 <pre class="highlight"><code>template<size_t I, class... T>
2418 constexpr const variant_alternative_t<I, variant<T...>>&
2419 get(const variant<T...>& v);</code></pre>
2422 <div class="listingblock">
2423 <div class="content">
2424 <pre class="highlight"><code>template<size_t I, class... T>
2425 constexpr const variant_alternative_t<I, variant<T...>>&&
2426 get(const variant<T...>&& v);</code></pre>
2429 <div class="ulist none">
2435 <dt class="hdlist1">Effects: </dt>
2437 <p>If <code>v.index()</code> is <code>I</code>, returns a reference to the object stored in
2438 the variant. Otherwise, throws <code>bad_variant_access</code>.</p>
2440 <dt class="hdlist1">Remarks: </dt>
2442 <p>These functions do not participate in overload resolution
2443 unless <code>I</code> < <code>sizeof…​(T)</code>.</p>
2450 <div class="listingblock">
2451 <div class="content">
2452 <pre class="highlight"><code>template<class U, class... T>
2453 constexpr U& get(variant<T...>& v);</code></pre>
2456 <div class="listingblock">
2457 <div class="content">
2458 <pre class="highlight"><code>template<class U, class... T>
2459 constexpr U&& get(variant<T...>&& v);</code></pre>
2462 <div class="listingblock">
2463 <div class="content">
2464 <pre class="highlight"><code>template<class U, class... T>
2465 constexpr const U& get(const variant<T...>& v);</code></pre>
2468 <div class="listingblock">
2469 <div class="content">
2470 <pre class="highlight"><code>template<class U, class... T>
2471 constexpr const U&& get(const variant<T...>&& v);</code></pre>
2474 <div class="ulist none">
2480 <dt class="hdlist1">Requires: </dt>
2482 <p>The type <code>U</code> occurs exactly once in <code>T…​</code>. Otherwise, the
2483 program is ill-formed.</p>
2485 <dt class="hdlist1">Effects: </dt>
2487 <p>If <code>v</code> holds a value of type <code>U</code>, returns a reference to that value.
2488 Otherwise, throws <code>bad_variant_access</code>.</p>
2497 <h4 id="ref_get_if">get_if</h4>
2498 <div class="listingblock">
2499 <div class="content">
2500 <pre class="highlight"><code>template<size_t I, class... T>
2501 constexpr add_pointer_t<variant_alternative_t<I, variant<T...>>>
2502 get_if(variant<T...>* v) noexcept;</code></pre>
2505 <div class="listingblock">
2506 <div class="content">
2507 <pre class="highlight"><code>template<size_t I, class... T>
2508 constexpr add_pointer_t<const variant_alternative_t<I, variant<T...>>>
2509 get_if(const variant<T...>* v) noexcept;</code></pre>
2512 <div class="ulist none">
2518 <dt class="hdlist1">Effects: </dt>
2520 <p>A pointer to the value stored in the variant, if
2521 <code>v != nullptr && v->index() == I</code>. Otherwise, <code>nullptr</code>.</p>
2523 <dt class="hdlist1">Remarks: </dt>
2525 <p>These functions do not participate in overload resolution
2526 unless <code>I</code> < <code>sizeof…​(T)</code>.</p>
2533 <div class="listingblock">
2534 <div class="content">
2535 <pre class="highlight"><code>template<class U, class... T>
2536 constexpr add_pointer_t<U>
2537 get_if(variant<T...>* v) noexcept;</code></pre>
2540 <div class="listingblock">
2541 <div class="content">
2542 <pre class="highlight"><code>template<class U, class... T>
2543 constexpr add_pointer_t<const U>
2544 get_if(const variant<T...>* v) noexcept;</code></pre>
2547 <div class="ulist none">
2553 <dt class="hdlist1">Requires: </dt>
2555 <p>The type <code>U</code> occurs exactly once in <code>T…​</code>. Otherwise, the
2556 program is ill-formed.</p>
2558 <dt class="hdlist1">Effects: </dt>
2560 <p>Equivalent to: <code>return get_if<I>(v);</code> with <code>I</code> being
2561 the zero-based index of <code>U</code> in <code>T…​</code>.</p>
2570 <h4 id="ref_relational_operators">Relational Operators</h4>
2571 <div class="listingblock">
2572 <div class="content">
2573 <pre class="highlight"><code>template<class... T>
2574 constexpr bool operator==(const variant<T...>& v, const variant<T...>& w);</code></pre>
2577 <div class="ulist none">
2583 <dt class="hdlist1">Returns: </dt>
2585 <p><code>v.index() == w.index() && get<I>(v) == get<I>(w)</code>, where <code>I</code>
2586 is <code>v.index()</code>.</p>
2593 <div class="listingblock">
2594 <div class="content">
2595 <pre class="highlight"><code>template<class... T>
2596 constexpr bool operator!=(const variant<T...>& v, const variant<T...>& w);</code></pre>
2599 <div class="ulist none">
2605 <dt class="hdlist1">Returns: </dt>
2607 <p><code>!(v == w)</code>.</p>
2614 <div class="listingblock">
2615 <div class="content">
2616 <pre class="highlight"><code>template<class... T>
2617 constexpr bool operator<(const variant<T...>& v, const variant<T...>& w);</code></pre>
2620 <div class="ulist none">
2626 <dt class="hdlist1">Returns: </dt>
2628 <p><code>v.index() < w.index() || (v.index() == w.index() && get<I>(v) < get<I>(w))</code>,
2629 where <code>I</code> is <code>v.index()</code>.</p>
2636 <div class="listingblock">
2637 <div class="content">
2638 <pre class="highlight"><code>template<class... T>
2639 constexpr bool operator>(const variant<T...>& v, const variant<T...>& w);</code></pre>
2642 <div class="ulist none">
2648 <dt class="hdlist1">Returns: </dt>
2650 <p><code>w < v</code>.</p>
2657 <div class="listingblock">
2658 <div class="content">
2659 <pre class="highlight"><code>template<class... T>
2660 constexpr bool operator<=(const variant<T...>& v, const variant<T...>& w);</code></pre>
2663 <div class="ulist none">
2669 <dt class="hdlist1">Returns: </dt>
2671 <p><code>v.index() < w.index() || (v.index() == w.index() && get<I>(v) <= get<I>(w))</code>,
2672 where <code>I</code> is <code>v.index()</code>.</p>
2679 <div class="listingblock">
2680 <div class="content">
2681 <pre class="highlight"><code>template<class... T>
2682 constexpr bool operator>=(const variant<T...>& v, const variant<T...>& w);</code></pre>
2685 <div class="ulist none">
2691 <dt class="hdlist1">Returns: </dt>
2693 <p><code>w <= v</code>.</p>
2702 <h4 id="ref_visit">visit</h4>
2703 <div class="listingblock">
2704 <div class="content">
2705 <pre class="highlight"><code>template<class F, class... V>
2706 constexpr /*see below*/ visit(F&& f, V&&... v);</code></pre>
2709 <div class="ulist none">
2715 <dt class="hdlist1">Returns: </dt>
2717 <p><code>std::forward<F>(f)(get<I>(std::forward<V>(v))…​)</code>, where
2718 <code>I…​</code> is <code>v.index()…​</code>.</p>
2727 <h4 id="ref_swap_2">swap</h4>
2728 <div class="listingblock">
2729 <div class="content">
2730 <pre class="highlight"><code>template<class... T>
2731 void swap(variant<T...>& v, variant<T...>& w) noexcept( /*see below*/ );</code></pre>
2734 <div class="ulist none">
2740 <dt class="hdlist1">Effects: </dt>
2742 <p>Equivalent to <code>v.swap(w)</code>.</p>
2751 <h4 id="ref_bad_variant_access">bad_variant_access</h4>
2752 <div class="listingblock">
2753 <div class="content">
2754 <pre class="highlight"><code>class bad_variant_access: public std::exception
2758 bad_variant_access() noexcept = default;
2760 char const * what() const noexcept
2762 return "bad_variant_access";
2772 <h2 id="copyright">Copyright and License</h2>
2773 <div class="sectionbody">
2774 <div class="paragraph">
2775 <p>This documentation is copyright 2018, 2019 Peter Dimov and is distributed under
2776 the <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License, Version 1.0</a>.</p>
2782 <div id="footer-text">
2783 Last updated 2019-12-10 00:20:09 UTC
2788 *:not(pre)>code { background: none; color: #600000; }
2789 :not(pre):not([class^=L])>code { background: none; color: #600000; }