<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.16">
<title>std::span and the missing constructor</title>
<style>
/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment the following line when using as a custom stylesheet */
/* @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"; */
html{font-family:sans-serif;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
b,strong{font-weight:bold}
abbr{font-size:.9em}
abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}
dfn{font-style:italic}
hr{height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type=checkbox],input[type=radio]{padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,::before,::after{box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.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}
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}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
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}
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}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal}
table thead,table tfoot{background:#f7f8f7}
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}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre).nobreak{word-wrap:normal}
:not(pre).nowrap{white-space:nowrap}
:not(pre).pre-wrap{white-space:pre-wrap}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
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:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#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:flex;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#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}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background:#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}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#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}
#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}
#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}
#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}
#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}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details{margin-left:1.25rem}
details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;-webkit-tap-highlight-color:transparent}
details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}
details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}
details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}
.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}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.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)}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.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}
.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.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:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos{border-right:1px solid;opacity:.35;padding-right:.5em}
pre.pygments .lineno{border-right:1px solid;opacity:.35;display:inline-block;margin-right:.75em}
pre.pygments .lineno::before{content:"";margin-right:-.125em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.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}
.quoteblock blockquote{margin:0;padding:0;border:0}
.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)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.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}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>*>tr>*{border-width:1px}
table.grid-cols>*>tr>*{border-width:0 1px}
table.grid-rows>*>tr>*{border-width:1px 0}
table.frame-all{border-width:1px}
table.frame-ends{border-width:1px 0}
table.frame-sides{border-width:0 1px}
table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd),table.stripes-even tr:nth-of-type(even),table.stripes-hover tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
ul.checklist>li>p:first-child{margin-left:-1em}
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}
ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em}
ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
td.hdlist2{word-wrap:anywhere}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;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}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt,summary{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]{border-bottom:1px dotted}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#header,#content,#footnotes,#footer{max-width:none}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
<style>
pre { line-height: 125%; margin: 0; }
td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
pre.pygments .hll { background-color: #ffffcc }
pre.pygments { background: #f8f8f8; }
pre.pygments .tok-c { color: #408080; font-style: italic } /* Comment */
pre.pygments .tok-err { border: 1px solid #FF0000 } /* Error */
pre.pygments .tok-k { color: #008000; font-weight: bold } /* Keyword */
pre.pygments .tok-o { color: #666666 } /* Operator */
pre.pygments .tok-ch { color: #408080; font-style: italic } /* Comment.Hashbang */
pre.pygments .tok-cm { color: #408080; font-style: italic } /* Comment.Multiline */
pre.pygments .tok-cp { color: #BC7A00 } /* Comment.Preproc */
pre.pygments .tok-cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
pre.pygments .tok-c1 { color: #408080; font-style: italic } /* Comment.Single */
pre.pygments .tok-cs { color: #408080; font-style: italic } /* Comment.Special */
pre.pygments .tok-gd { color: #A00000 } /* Generic.Deleted */
pre.pygments .tok-ge { font-style: italic } /* Generic.Emph */
pre.pygments .tok-gr { color: #FF0000 } /* Generic.Error */
pre.pygments .tok-gh { color: #000080; font-weight: bold } /* Generic.Heading */
pre.pygments .tok-gi { color: #00A000 } /* Generic.Inserted */
pre.pygments .tok-go { color: #888888 } /* Generic.Output */
pre.pygments .tok-gp { color: #000080; font-weight: bold } /* Generic.Prompt */
pre.pygments .tok-gs { font-weight: bold } /* Generic.Strong */
pre.pygments .tok-gu { color: #800080; font-weight: bold } /* Generic.Subheading */
pre.pygments .tok-gt { color: #0044DD } /* Generic.Traceback */
pre.pygments .tok-kc { color: #008000; font-weight: bold } /* Keyword.Constant */
pre.pygments .tok-kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
pre.pygments .tok-kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
pre.pygments .tok-kp { color: #008000 } /* Keyword.Pseudo */
pre.pygments .tok-kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
pre.pygments .tok-kt { color: #B00040 } /* Keyword.Type */
pre.pygments .tok-m { color: #666666 } /* Literal.Number */
pre.pygments .tok-s { color: #BA2121 } /* Literal.String */
pre.pygments .tok-na { color: #7D9029 } /* Name.Attribute */
pre.pygments .tok-nb { color: #008000 } /* Name.Builtin */
pre.pygments .tok-nc { color: #0000FF; font-weight: bold } /* Name.Class */
pre.pygments .tok-no { color: #880000 } /* Name.Constant */
pre.pygments .tok-nd { color: #AA22FF } /* Name.Decorator */
pre.pygments .tok-ni { color: #999999; font-weight: bold } /* Name.Entity */
pre.pygments .tok-ne { color: #D2413A; font-weight: bold } /* Name.Exception */
pre.pygments .tok-nf { color: #0000FF } /* Name.Function */
pre.pygments .tok-nl { color: #A0A000 } /* Name.Label */
pre.pygments .tok-nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
pre.pygments .tok-nt { color: #008000; font-weight: bold } /* Name.Tag */
pre.pygments .tok-nv { color: #19177C } /* Name.Variable */
pre.pygments .tok-ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
pre.pygments .tok-w { color: #bbbbbb } /* Text.Whitespace */
pre.pygments .tok-mb { color: #666666 } /* Literal.Number.Bin */
pre.pygments .tok-mf { color: #666666 } /* Literal.Number.Float */
pre.pygments .tok-mh { color: #666666 } /* Literal.Number.Hex */
pre.pygments .tok-mi { color: #666666 } /* Literal.Number.Integer */
pre.pygments .tok-mo { color: #666666 } /* Literal.Number.Oct */
pre.pygments .tok-sa { color: #BA2121 } /* Literal.String.Affix */
pre.pygments .tok-sb { color: #BA2121 } /* Literal.String.Backtick */
pre.pygments .tok-sc { color: #BA2121 } /* Literal.String.Char */
pre.pygments .tok-dl { color: #BA2121 } /* Literal.String.Delimiter */
pre.pygments .tok-sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
pre.pygments .tok-s2 { color: #BA2121 } /* Literal.String.Double */
pre.pygments .tok-se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
pre.pygments .tok-sh { color: #BA2121 } /* Literal.String.Heredoc */
pre.pygments .tok-si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
pre.pygments .tok-sx { color: #008000 } /* Literal.String.Other */
pre.pygments .tok-sr { color: #BB6688 } /* Literal.String.Regex */
pre.pygments .tok-s1 { color: #BA2121 } /* Literal.String.Single */
pre.pygments .tok-ss { color: #19177C } /* Literal.String.Symbol */
pre.pygments .tok-bp { color: #008000 } /* Name.Builtin.Pseudo */
pre.pygments .tok-fm { color: #0000FF } /* Name.Function.Magic */
pre.pygments .tok-vc { color: #19177C } /* Name.Variable.Class */
pre.pygments .tok-vg { color: #19177C } /* Name.Variable.Global */
pre.pygments .tok-vi { color: #19177C } /* Name.Variable.Instance */
pre.pygments .tok-vm { color: #19177C } /* Name.Variable.Magic */
pre.pygments .tok-il { color: #666666 } /* Literal.Number.Integer.Long */
</style>
</head>
<body class="article">
<div id="header">
<h1><code>std::span</code> and the missing constructor</h1>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Document number:</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">P2447R1</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Date:</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2021-12-11</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Project:</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Programming Language C++, Library Working Group</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Reply-to:</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="mailto:federico.kircheis@gmail.com">federico.kircheis@gmail.com</a></p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect1">
<h2 id="_motivation">1. Motivation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Given the functions signature <code>void foo(std::span&lt;const int&gt;);</code>, how to call <code>foo</code> with a constant set of values?</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">before</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">after</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({});</span></code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({});</span></code></pre>
</div>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div>
<div class="paragraph">
<p><code>// compiler error</code><br>
<code>// could not convert '{1,2,3}' from '&lt;brace-enclosed initializer list&gt;' to 'std::span&lt;const int&gt;'</code></p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-kt">int</span> <span class="tok-n">data</span><span class="tok-p">[]{</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">};</span>
<span class="tok-n">foo</span><span class="tok-p">(</span><span class="tok-n">data</span><span class="tok-p">);</span></code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">(</span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">vector</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">&gt;</span><span class="tok-p">{</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">(</span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">initializer_list</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">&gt;</span><span class="tok-p">{</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({{</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">}});</span></code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">template</span><span class="tok-o">&lt;</span><span class="tok-k">class</span> <span class="tok-nc">T</span><span class="tok-o">&gt;</span>
<span class="tok-k">using</span> <span class="tok-n">raw_array</span> <span class="tok-o">=</span> <span class="tok-n">T</span><span class="tok-p">[];</span>

<span class="tok-n">foo</span><span class="tok-p">(</span><span class="tok-n">raw_array</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">&gt;</span><span class="tok-p">{</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">using</span> <span class="tok-n">int_array</span> <span class="tok-o">=</span> <span class="tok-kt">int</span><span class="tok-p">[];</span>

<span class="tok-n">foo</span><span class="tok-p">(</span><span class="tok-n">int_array</span><span class="tok-p">{</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">(</span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">array</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">}));</span></code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-cm">/* define somewhere a helper function as_span that takes an initializer_list and returns a span */</span>
<span class="tok-n">foo</span><span class="tok-p">(</span><span class="tok-n">as_span</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">}));</span></code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-cm">/* define an overload for foo somewhere */</span>
<span class="tok-kt">void</span> <span class="tok-nf">foo</span><span class="tok-p">(</span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">initializer_list</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">&gt;</span> <span class="tok-n">il</span><span class="tok-p">){</span>
	<span class="tok-k">return</span> <span class="tok-n">foo</span><span class="tok-p">(</span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">span</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">&gt;</span><span class="tok-p">(</span><span class="tok-n">il</span><span class="tok-p">));</span>
<span class="tok-p">}</span>

<span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div></div></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The fact that it is not possible in an easy and natural way to create a span over a set of given values is the main motivation for this paper.</p>
</div>
<div class="paragraph">
<p>Following pattern:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>does currently not compile, as <code>std::span</code> does not have a constructor that takes an <code>std::initializer_list</code>.</p>
</div>
<div class="paragraph">
<p>Note that in the case of an empty container, <code>foo({});</code> compiles making the construction of span apparently inconsistent.</p>
</div>
<div class="paragraph">
<p>The after/before table shows different types of workarounds on how to handle such situation.</p>
</div>
<div class="paragraph">
<p>The most trivial workaround is creating an array, and pass it to <code>foo</code>.
This introduces a variable that was not there before, which also has a much bigger scope (which might or might be not an issue), thus this approach has a clear drawback.</p>
</div>
<div class="paragraph">
<p>Notice that one could also use a local <code>std::initializer_list</code>, and <code>std::span</code> range constructor will accept it without issues.</p>
</div>
<div class="paragraph">
<p>Another approach is creating a temporary container, the easiest one to write ist <code>std::vector</code>, but doing so introduce unnecessary overhead.</p>
</div>
<div class="paragraph">
<p>One could of course create a temporary array, which is more subtle than it needs to be, or <code>std::array</code>.</p>
</div>
<div class="paragraph">
<p>Another alternative is writing a helper function, that takes a set of values and converts them to a span.</p>
</div>
<div class="paragraph">
<p>When using <code>std::array</code>, the syntax between empty and non-empty <code>std::array</code> is inconsistent, unless one does not take advantage of class template argument deduction, as <code>foo(std::array{1,2,3})</code> compiles, but <code>foo(std::array{})</code> does not.
Writing the size by hand is not really user-friendly, but at least would make the code consistent, as both <code>foo(std::array&lt;int,3&gt;{1,2,3});</code> and <code>foo(std::array&lt;int,0&gt;{});</code> compiles.</p>
</div>
<div class="paragraph">
<p>Last but not least, one can write <code>foo({{1,2,3}})</code>, which picks the array overload.
This is probably the best/less verbose approach, but the syntax is uncommon, the reasons which overloads gets picked unclear and it is also easy to oversee the second pair of brackets.
But, this syntax is inconsistent when dealing with empty spans, as <code>foo({{}})</code> does not compile.</p>
</div>
<div class="paragraph">
<p>Spelling <code>std::initializer_list&lt;int&gt;</code> out makes the code compile.
As normally one would not write <code>std::initializer_list</code> when initializing a container, it makes span construction awkward.</p>
</div>
<div class="paragraph">
<p>To sum it up:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>in all cases, to call <code>foo</code> with a given set of values, it is necessary to manually add some sort of indirection.</p>
</li>
<li>
<p>the less verbose approach is the less obvious</p>
</li>
<li>
<p>the simplest approaches (temporary vector, local container) have drawbacks</p>
</li>
<li>
<p>all approaches, except using a helper function, spelling <code>std::initializer_list</code> out or using <code>std::array</code> without type deduction, are inconsistent between empty and non-empty spans.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>This makes <code>std::span</code> somewhat more difficult to use.</p>
</div>
<div class="sect2">
<h3 id="_upgrading_from_vector">1.1. Upgrading from vector</h3>
<div class="paragraph">
<p>While the main motivation for adding another constructor to span has already been presented, the "historical" motivation that led to the creation of this paper is the introduction of <code>std::span</code> in existing code.</p>
</div>
<div class="paragraph">
<p>Consider the following function signature:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-kt">void</span> <span class="tok-nf">foo</span><span class="tok-p">(</span><span class="tok-k">const</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">vector</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">&gt;&amp;</span><span class="tok-p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>As the parameter is passed by const-reference, and <code>foo</code> does not need the ownership of the data, using <code>std::vector</code> is often suboptimal especially since we have <code>std::span</code>.</p>
</div>
<div class="paragraph">
<p>"upgrading"/"enhancing" the function signature to</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-kt">void</span> <span class="tok-nf">foo</span><span class="tok-p">(</span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">span</span><span class="tok-o">&lt;</span><span class="tok-k">const</span> <span class="tok-kt">int</span><span class="tok-o">&gt;</span><span class="tok-p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>is a code incompatible change for the user of such function.
Even recompiling the whole codebase (thus ignoring ABI issues) can lead to compiler errors.</p>
</div>
<div class="paragraph">
<p>Even if there are trivial code-transformation for fixing the signature incompatibility it is harder to introduce <code>std::span</code> in a bigger and older codebase.</p>
</div>
<div class="paragraph">
<p>The <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1024r3.pdf">Usability Enhancements for std::span</a> paper, gives another reason why we should have a constructor for <code>std::initializer_list</code> (emphasis added):</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="paragraph">
<p>A span is [&#8230;&#8203;]. It is intended as a new "vocabulary type" for contiguous ranges, replacing the use of(pointer, length) pairs and, in some cases, <strong>vector&lt;T, A&gt;&amp; function parameters.</strong></p>
</div>
</blockquote>
<div class="attribution">
&#8212; Usability Enhancements for `std::span`
</div>
</div>
<div class="paragraph">
<p>This can be also read from the original <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0122r1.pdf">span paper</a>:</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="paragraph">
<p>To simplify use of span as a simple parameter, span offers a number of constructors for common container types that store contiguous sequences of elements.</p>
</div>
</blockquote>
<div class="attribution">
&#8212; span: bounds-safe views for sequences of objects
</div>
</div>
<div class="paragraph">
<p>Upgrading <code>void foo(const std::vector&lt;int&gt;&amp;);</code> to <code>void foo(std::span&lt;const int&gt;);</code> is one of the main use-cases of <code>std::span</code>.</p>
</div>
<div class="paragraph">
<p>It is desirable that the transition from one function signature to another is as smooth and error-free as possible.</p>
</div>
<div class="paragraph">
<p>The current incompatibility adds unnecessary work to the users of the function.
Making such change might thus not be possible, especially for a public API.</p>
</div>
<div class="sect3">
<h4 id="_does_that_imply_that_stdspan_should_have_all_constructors_of_stdvector_or_other_container_with_sequential_storage">1.1.1. Does that imply that <code>std::span</code> should have all constructors of <code>std::vector</code> (or other container with sequential storage)?</h4>
<div class="paragraph">
<p>No.</p>
</div>
<div class="paragraph">
<p>While one could write</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-kt">void</span> <span class="tok-nf">f</span><span class="tok-p">(</span><span class="tok-k">const</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">vector</span><span class="tok-o">&lt;</span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">string</span><span class="tok-o">&gt;&amp;</span><span class="tok-p">);</span>

<span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-mi">4</span><span class="tok-p">,</span> <span class="tok-s">&quot;hello&quot;</span><span class="tok-p">});</span> <span class="tok-c1">// vector with 4 times the string &quot;hello&quot;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>if span would support <code>std::initializer_list</code> such code would still not compile.</p>
</div>
<div class="paragraph">
<p>Nevertheless, based on personal experience, most temporary vectors (or other containers) are either constructed from a constant set of values (thus with a <code>std::initializer_list</code>), or empty.</p>
</div>
<div class="paragraph">
<p>Thus while it is true that even if this paper gets accepted the upgrade process from <code>std::vector</code> to <code>std::span</code> is still a breaking change, the chances of breaking existing code are much lower.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_why_doesnt_span_have_a_stdinitializer_list_constructor">1.2. Why doesn&#8217;t span have a <code>std::initializer_list</code> constructor?</h3>
<div class="paragraph">
<p>As a matter of fact it is possible to create a span from an <code>std::initializer_list</code> by spelling the type out.</p>
</div>
<div class="paragraph">
<p>The absence of such constructor seems to imply that a span should not be constructed from an <code>std::initializer_list</code> (as normally one does not spell <code>std::initializer_list</code> out).</p>
</div>
<div class="paragraph">
<p>I could not find any rationale for not adding such constructor, except those presented in this issue: <a href="https://github.com/Microsoft/GSL/issues/459" class="bare">https://github.com/Microsoft/GSL/issues/459</a></p>
</div>
<div class="sect3">
<h4 id="_dangling_spans">1.2.1. dangling spans</h4>
<div class="paragraph">
<p>The first argument is that if we added such a constructor, it would be easier to create a dangling span accidentally:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">span</span><span class="tok-o">&lt;</span><span class="tok-k">const</span> <span class="tok-kt">int</span><span class="tok-o">&gt;</span> <span class="tok-n">sp</span> <span class="tok-o">=</span> <span class="tok-p">{</span><span class="tok-mi">1</span><span class="tok-p">,</span> <span class="tok-mi">2</span><span class="tok-p">,</span> <span class="tok-mi">3</span><span class="tok-p">};</span>  <span class="tok-c1">// dangles immediately</span>
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">span</span> <span class="tok-n">sp</span><span class="tok-p">{</span><span class="tok-mi">1</span><span class="tok-p">,</span> <span class="tok-mi">2</span><span class="tok-p">,</span> <span class="tok-mi">3</span><span class="tok-p">};</span>  <span class="tok-c1">// dangles immediately</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>However, this argument seems weak, because it is already possible to create a dangling span variable in many ways. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span>
<span class="tok-c1">// ---</span>
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">span</span><span class="tok-o">&lt;</span><span class="tok-k">const</span> <span class="tok-kt">int</span><span class="tok-o">&gt;</span> <span class="tok-n">sp</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">vector</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">&gt;</span><span class="tok-p">{</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">};</span> <span class="tok-c1">// dangles immediately</span>

<span class="tok-c1">// ---</span>
<span class="tok-c1">// suppose that std::span&lt;const int&gt; bar(); changed to</span>
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">vector</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">&gt;</span> <span class="tok-n">bar</span><span class="tok-p">();</span>

<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">span</span><span class="tok-o">&lt;</span><span class="tok-k">const</span> <span class="tok-kt">int</span><span class="tok-o">&gt;</span> <span class="tok-n">sp</span> <span class="tok-o">=</span> <span class="tok-n">bar</span><span class="tok-p">();</span> <span class="tok-c1">// dangles immediately</span>

<span class="tok-c1">// ---</span>
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">span</span><span class="tok-o">&lt;</span><span class="tok-k">const</span> <span class="tok-kt">int</span><span class="tok-o">&gt;</span> <span class="tok-n">sp</span><span class="tok-p">;</span>
<span class="tok-p">{</span>
  <span class="tok-k">const</span> <span class="tok-k">auto</span> <span class="tok-n">v</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">vector</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">&gt;</span><span class="tok-p">{</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">};</span>
  <span class="tok-n">sp</span> <span class="tok-o">=</span> <span class="tok-n">v</span><span class="tok-p">;</span>
<span class="tok-p">}</span>
<span class="tok-c1">// dangling sp</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>rvalues are not necessarily short-lived, and the lifetime of an lvalue might be shorter than the lifetime of the constructed span.</p>
</div>
<div class="paragraph">
<p>Thus using value categories for determining the life-time, as in this case (if the motivation found on GitHub is the one why span does not have the proposed constructor), gives a false sense of security, and disallows valid use-cases.</p>
</div>
<div class="paragraph">
<p><code>std::span</code> behaves like a pointer and an associated size, as it does not own the resource (just like <code>std::string_view</code>).
Thus dangling spans are unavoidable, just like dangling references and pointers.
Fortunately, it is possible to <a href="https://godbolt.org/z/Kxocq5qqv">diagnose those type of errors statically</a> without making span harder to use.</p>
</div>
</div>
<div class="sect3">
<h4 id="_span_is_a_view_over_a_container">1.2.2. span is a view over a container</h4>
<div class="paragraph">
<p>The other presented argument is that span is a view over a container, and that <code>std::initializer_list</code> is not a container.</p>
</div>
<div class="paragraph">
<p>A <code>std::span</code> can be constructed from "something" that is contiguous memory (<code>std::ranges::data</code> and <code>std::ranges::size</code> needs to work on it).
That "something" does thus not even need to be a container.<br>
Also a pointer and a length are not a container, yet there is a constructor for it, as this is another main use-case for span.</p>
</div>
<div class="paragraph">
<p><code>std::initializer_list</code> might not be defined as a container, but</p>
</div>
<div class="ulist">
<ul>
<li>
<p>it has contiguous memory</p>
</li>
<li>
<p>it has a container-like interface (member functions <code>begin</code>, <code>end</code> and  <code>size</code>, not even an <code>array</code> has those. It also has free functions for <code>cbegin</code>, <code>rbegin</code>, &#8230;&#8203;)</p>
</li>
<li>
<p><code>std::span</code> can be already constructed from a <code>std::initializer_list</code>, one must "just" be very explicit about it when writing it in code.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>As it is possible to create a span from a <code>std::initializer_list</code>, and as <code>std::initializer_list</code> can be used like a container (just like span), the distinction for span between a <code>std::initializer_list</code> and other containers is artificial.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_this_is_a_breaking_change">1.3. This is a breaking change</h3>
<div class="paragraph">
<p>Unfortunately, adding a <code>std::initializer_list</code> constructor is a breaking change.</p>
</div>
<div class="paragraph">
<p>Currently, when using <code>{ /* &#8230;&#8203; */ }</code> a constructor not taking <code>std::initializer_list</code> will be called.
With this paper, depending on the arguments, the constructor taking <code>std::initializer_list</code> might be called.</p>
</div>
<div class="paragraph">
<p>As the proposed constructor for <code>std::initializer_list</code> is constrained for a span over constant elements, the breakage is reduced to a subset of types with unconstrained constructor when creating a span.</p>
</div>
<div class="paragraph">
<p>For those examples, the code behavior is unchanged as the constraint rules the new constructor out:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">const</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">vector</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">&gt;</span><span class="tok-p">;</span>

<span class="tok-k">auto</span> <span class="tok-n">sp1</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">span</span><span class="tok-p">{</span><span class="tok-n">v</span><span class="tok-p">};</span>
<span class="tok-k">auto</span> <span class="tok-n">sp2</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">span</span><span class="tok-p">{</span><span class="tok-n">v</span><span class="tok-p">.</span><span class="tok-n">begin</span><span class="tok-p">(),</span> <span class="tok-n">v</span><span class="tok-p">.</span><span class="tok-n">end</span><span class="tok-p">()};</span>
<span class="tok-k">auto</span> <span class="tok-n">begin</span> <span class="tok-o">=</span> <span class="tok-n">v</span><span class="tok-p">.</span><span class="tok-n">data</span><span class="tok-p">();</span>
<span class="tok-k">auto</span> <span class="tok-n">end</span> <span class="tok-o">=</span> <span class="tok-n">begin</span> <span class="tok-o">+</span> <span class="tok-n">v</span><span class="tok-p">.</span><span class="tok-n">size</span><span class="tok-p">();</span>
<span class="tok-k">auto</span> <span class="tok-n">sp3</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">span</span><span class="tok-p">{</span><span class="tok-n">v</span><span class="tok-p">.</span><span class="tok-n">begin</span><span class="tok-p">(),</span> <span class="tok-n">v</span><span class="tok-p">.</span><span class="tok-n">end</span><span class="tok-p">()};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>To use the <code>std::initializer_list</code> constructor, one needs to spell the type out:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">const</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">vector</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">&gt;</span><span class="tok-p">;</span>

<span class="tok-k">auto</span> <span class="tok-n">sp1</span> <span class="tok-o">=</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">span</span><span class="tok-o">&lt;</span><span class="tok-k">const</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">vector</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">&gt;&gt;</span><span class="tok-p">{</span><span class="tok-n">v</span><span class="tok-p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Types with unconstrained constructors, for example <code>void*</code> and <code>std::any</code>, are those who are affected by the new constructor:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-kt">void</span> <span class="tok-nf">foo</span><span class="tok-p">(</span><span class="tok-n">span</span><span class="tok-o">&lt;</span><span class="tok-kt">void</span><span class="tok-o">*</span> <span class="tok-k">const</span><span class="tok-o">&gt;</span> <span class="tok-n">s</span><span class="tok-p">);</span>


<span class="tok-c1">// without this paper, creates a span with one void*</span>
<span class="tok-c1">// with this paper, creates a span of two void*</span>
<span class="tok-kt">void</span><span class="tok-o">*</span> <span class="tok-n">vp</span> <span class="tok-o">=</span> <span class="tok-k">nullptr</span><span class="tok-p">;</span>
<span class="tok-n">span</span><span class="tok-o">&lt;</span><span class="tok-kt">void</span><span class="tok-o">*</span> <span class="tok-k">const</span><span class="tok-o">&gt;</span> <span class="tok-n">sp</span><span class="tok-p">{</span><span class="tok-o">&amp;</span><span class="tok-n">vp</span><span class="tok-p">,</span> <span class="tok-o">&amp;</span><span class="tok-n">vp</span><span class="tok-o">+</span><span class="tok-mi">1</span><span class="tok-p">};</span>



<span class="tok-c1">// without this paper, creates a span with one std::any*</span>
<span class="tok-c1">// with this paper, creates a span of two elements</span>
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">any</span> <span class="tok-n">a</span><span class="tok-p">;</span>
<span class="tok-n">span</span><span class="tok-o">&lt;</span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">any</span><span class="tok-o">&gt;</span> <span class="tok-n">sa</span><span class="tok-p">{</span><span class="tok-o">&amp;</span><span class="tok-n">ap</span><span class="tok-p">,</span> <span class="tok-o">&amp;</span><span class="tok-n">ap</span><span class="tok-o">+</span><span class="tok-mi">1</span><span class="tok-p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>One of the main use-cases for span is being used as a function parameter:</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="paragraph">
<p>One of the major advantages of span over the common idiom of a “pointer plus length” pair of parameters is that it [&#8230;&#8203;]</p>
</div>
</blockquote>
<div class="attribution">
&#8212; span: bounds-safe views for sequences of objects
</div>
</div>
<div class="paragraph">
<p>For those intended use-cases the breaking change will be very uncommon as the type is normally spelled out.</p>
</div>
<div class="paragraph">
<p>For example, if a function signature would have been</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-kt">void</span> <span class="tok-nf">foo</span><span class="tok-p">(</span><span class="tok-k">const</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">vector</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">*&gt;&amp;</span><span class="tok-p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>when changing it to</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-kt">void</span> <span class="tok-nf">foo</span><span class="tok-p">(</span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">span</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">*</span> <span class="tok-k">const</span><span class="tok-o">&gt;</span><span class="tok-p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>then</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-kt">int</span><span class="tok-o">*</span> <span class="tok-n">ptr1</span> <span class="tok-o">=</span> <span class="tok-p">...;</span>
<span class="tok-kt">int</span><span class="tok-o">*</span> <span class="tok-n">ptr2</span> <span class="tok-o">=</span> <span class="tok-p">...;</span>
<span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-n">ptr1</span><span class="tok-p">,</span> <span class="tok-n">ptr2</span><span class="tok-p">});</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>can only be interpreted as a <code>std::span&lt;int* const&gt;</code> constructed with an <code>std::initializer_list&lt;int*&gt;</code>, and not a <code>std::span&lt;int* const&gt;</code> created from a pair of iterators.</p>
</div>
<div class="paragraph">
<p>If the type is not spelled out, as in</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">template</span> <span class="tok-o">&lt;</span><span class="tok-k">class</span> <span class="tok-nc">T</span><span class="tok-o">&gt;</span>
<span class="tok-kt">void</span> <span class="tok-n">foo</span><span class="tok-p">(</span><span class="tok-n">span</span><span class="tok-o">&lt;</span><span class="tok-n">conts</span> <span class="tok-n">T</span><span class="tok-o">&gt;</span> <span class="tok-n">s</span><span class="tok-p">){</span><span class="tok-cm">/* ... */</span><span class="tok-p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>then class template argument deduction generally will not work:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-kt">int</span><span class="tok-o">*</span> <span class="tok-n">begin</span> <span class="tok-o">=</span> <span class="tok-k">nullptr</span><span class="tok-p">;</span>
<span class="tok-kt">int</span><span class="tok-o">*</span> <span class="tok-n">end</span> <span class="tok-o">=</span> <span class="tok-k">nullptr</span><span class="tok-p">;</span>
<span class="tok-n">foo</span><span class="tok-p">({</span><span class="tok-n">begin</span><span class="tok-p">,</span> <span class="tok-n">end</span><span class="tok-p">});</span>
<span class="tok-cm">/*</span>
<span class="tok-cm">error: no matching function for call to &#39;foo(&lt;brace-enclosed initializer list&gt;)&#39;</span>
<span class="tok-cm"> foo({begin, end});</span>
<span class="tok-cm"> ~~~^~~~~~~~~~~~~~</span>
<span class="tok-cm">note: candidate: &#39;template&lt;class T&gt; void foo(std::span&lt;const T&gt;)&#39;</span>
<span class="tok-cm">void foo(std::span&lt;const T&gt; s){}</span>
<span class="tok-cm">      ^~~</span>
<span class="tok-cm">note:   template argument deduction/substitution failed:</span>
<span class="tok-cm">note:   couldn&#39;t deduce template parameter &#39;T&#39;</span>
<span class="tok-cm"> foo({begin, end});</span>
<span class="tok-cm"> ~~~^~~~~~~~~~~~~~</span>
<span class="tok-cm">*/</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>As the expected usage of <code>std::span</code> is to be used (A) as a parameter type and (B) with a non-deduced template argument, the breaking change (considering types like <code>std::span&lt;void*&gt;</code>) should not affect much code.</p>
</div>
<div class="paragraph">
<p>A similar contrived example, involving deduction and braced initializers, was successfully broken by DR between C&#43;&#43;14 and C&#43;&#43;17:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-k">auto</span> <span class="tok-n">x</span><span class="tok-p">{</span><span class="tok-mi">1</span><span class="tok-p">};</span>  <span class="tok-c1">// C++14: initializer_list&lt;int&gt;. C++17: int.</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Therefore, we hope that we can similarly get away with this breakage.</p>
</div>
<div class="paragraph">
<p>Another problematic situation arises when considering function overloads.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="pygments highlight"><code data-lang="cpp"><span></span><span class="tok-cp">#include</span> <span class="tok-cpf">&lt;span&gt;</span><span class="tok-cp"></span>
<span class="tok-cp">#include</span> <span class="tok-cpf">&lt;vector&gt;</span><span class="tok-cp"></span>

<span class="tok-kt">void</span> <span class="tok-nf">f</span><span class="tok-p">(</span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">span</span><span class="tok-o">&lt;</span><span class="tok-k">const</span> <span class="tok-kt">int</span><span class="tok-o">&gt;</span><span class="tok-p">);</span>

<span class="tok-kt">void</span> <span class="tok-nf">f</span><span class="tok-p">(</span><span class="tok-k">const</span> <span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">vector</span><span class="tok-o">&lt;</span><span class="tok-kt">int</span><span class="tok-o">&gt;&amp;</span><span class="tok-p">);</span>

<span class="tok-kt">int</span> <span class="tok-nf">main</span><span class="tok-p">()</span>
<span class="tok-p">{</span>
    <span class="tok-n">f</span><span class="tok-p">({</span><span class="tok-mi">1</span><span class="tok-p">,</span><span class="tok-mi">2</span><span class="tok-p">,</span><span class="tok-mi">3</span><span class="tok-p">});</span>
<span class="tok-p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>As of today, this code is valid and calls <code>f(const vector&lt;int&gt;)</code>.
If this paper gets accepted, the function call is ambiguous.</p>
</div>
<div class="paragraph">
<p>As <code>std::span</code> should be the vocabulary type for passing around non-owning contiguos range of memory, overloading for both <code>std::span&lt;const T&gt;</code> and <code>const std::vector&lt;T&gt;&amp;</code> should never be a necessity.
One would normally, as presented at the beginning of the paper and motivated in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0122r1.pdf">the original span paper</a>, replace <code>f(const std::vector&lt;int&gt;&amp;)</code> with <code>f(std::span&lt;const int&gt;)</code>, and not have both overloads.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_design_decisions">2. Design Decisions</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This is purely a library extension.</p>
</div>
<div class="paragraph">
<p>It is sufficient to add a constructor for <code>std::initializer_list</code> to <code>std::span</code>.</p>
</div>
<div class="paragraph">
<p>Similar to the constructors that takes an array, it is unconditionally <code>noexcept</code>, as none of the operations for creating a <code>std::span</code> over a <code>std::initializer_list</code> can fail.</p>
</div>
<div class="paragraph">
<p>Similarly to other constructors the proposed constructor is <code>explicit</code> if <code>extent != dynamic_extent</code>.</p>
</div>
<div class="paragraph">
<p>As <code>std::initializer_list</code> provides only constant access to the elements, this constructor is only available for a span over constant elements.
This also reduces the breaking changes to only a small subset of contrived examples.</p>
</div>
<div class="paragraph">
<p>A reference implementation provided by Arthur O&#8217;Dwyer for libc++ can be found on <a href="https://github.com/Quuxplusone/llvm-project/commit/span-ctor">on github</a>, he also provided a <a href="https://p1144.godbolt.org/z/aKz3PvMKP">playground on godbolt</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_proposed_wording_changes">3. Proposed Wording Changes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The following proposed wording changes against the working draft of the standard are relative to <a href="http://open-std.org/jtc1/sc22/wg21/docs/papers/2021/n4892.pdf">N4892</a>.</p>
</div>
<div class="paragraph">
<p>Apply following modifications to <code>Header span synopsis [span.syn]</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>#include &lt;initializer_list&gt;     // see [initializer.list.syn]

namespace std {
	// constants
	inline constexpr size_t dynamic_extent = numeric_limits&lt;size_t&gt;::max();</pre>
</div>
</div>
<div class="paragraph">
<p>Apply following modifications to definition of <code>Class template span[views.span]</code>, <code>Overview [span.overview]</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>template&lt;class ElementType, size_t Extent = dynamic_extent&gt;class span {
	public:// constants and types
	using element_type = ElementType;
	using value_type = remove_cv_t&lt;ElementType&gt;;
	using size_type = size_t;
	using difference_type = ptrdiff_t;
	using pointer = element_type*;
	using const_pointer = const element_type*;
	using reference = element_type&amp;;
	using const_reference = const element_type&amp;;
	using iterator =implementation-defined;// see 22.7.3.7
	using reverse_iterator = std::reverse_iterator&lt;iterator&gt;;
	static constexpr size_type extent = Extent;

	constexpr span() noexcept;
	template&lt;class It&gt;
	constexpr explicit(extent != dynamic_extent) span(It first, size_type count);
	template&lt;class It, class End&gt;
	constexpr explicit(extent != dynamic_extent) span(It first, End last);
	template&lt;size_t N&gt;
	constexpr span(type_identity_t&lt;element_type&gt; (&amp;arr)[N]) noexcept;
	template&lt;class T, size_t N&gt;
	constexpr span(array&lt;T, N&gt;&amp; arr) noexcept;
	template&lt;class T, size_t N&gt;
	constexpr span(const array&lt;T, N&gt;&amp; arr) noexcept;
	template&lt;class R&gt;
	constexpr explicit(extent != dynamic_extent) span(R&amp;&amp; r);
	<span class="underline">constexpr explicit(extent != dynamic_extent) span(std::initializer_list&lt;value_type&gt; il) noexcept;</span>
	constexpr span(const span&amp; other) noexcept = default;</pre>
</div>
</div>
<div class="paragraph">
<p>Add the following text to <code>Constructors, copy, and assignment [span.cons]</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre><span class="underline">constexpr explicit(extent != dynamic_extent) span(std::initializer_list&lt;value_type&gt; il) noexcept;</span></pre>
</div>
</div>
<div class="paragraph">
<p><span class="underline"><em>Constrains</em>: <code>is_const_v&lt;element_type&gt;</code> is <code>true</code>.</span><br>
<span class="underline"><em>Preconditions</em>: If <code>extent</code> is not equal to <code>dynamic_­extent</code>, then <code>il.size()</code> is equal to <code>extent</code>.</span><br>
<span class="underline"><em>Effects</em>: Initializes <code>data_</code> with <code>il.begin()</code> and <code>size_</code> with <code>il.size()</code>.</span></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_acknowledgements">4. Acknowledgements</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A big thank you to all those giving feedback for this paper.<br>
Especially Arthur O&#8217;Dwyer, Barry Revzin, Jonathan Wakely and Tomasz Kamiński for helping with the wording.</p>
</div>
</div>
</div>
</div>
</body>
</html>