{"id":5983,"date":"2020-09-08T18:54:21","date_gmt":"2020-09-08T18:54:21","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-20-std-span\/"},"modified":"2024-01-09T11:24:34","modified_gmt":"2024-01-09T11:24:34","slug":"c-20-std-span","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-20-std-span\/","title":{"rendered":"std::span in C++20:  Bounds-Safe Views for Sequences of Objects"},"content":{"rendered":"<p>In my seminar, I often hear the question: How can I safely pass a plain array to a function? With C++20, the answer is quite easy: Use a <span style=\"font-family: courier new, courier;\">std::span<\/span>.<\/p>\n<p><!--more--><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8904 size-full\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/TimelineCpp20CoreLanguageSpan.png\" alt=\"\" width=\"955\" height=\"375\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/TimelineCpp20CoreLanguageSpan.png 955w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/TimelineCpp20CoreLanguageSpan-300x118.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/TimelineCpp20CoreLanguageSpan-768x302.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/TimelineCpp20CoreLanguageSpan-705x277.png 705w\" sizes=\"auto, (max-width: 955px) 100vw, 955px\" \/><\/p>\n<p>\u00a0<\/p>\n<p>A <span style=\"font-family: courier new, courier;\">std::span<\/span> is an object that can refer to a contiguous sequence of objects. A <span style=\"font-family: courier new, courier;\">std::span<\/span>, sometimes also called a view, is never an owner. This contiguous memory can be a plain array, a pointer with a size, a <span style=\"font-family: courier new, courier;\">std::array<\/span>, a <span style=\"font-family: courier new, courier;\">std::vector, <\/span>or a <span style=\"font-family: courier new, courier;\">std::string<\/span>. A typical implementation consists of a pointer to its first element and a size. The main reason for having a <span style=\"font-family: courier new, courier;\">std::span&lt;T&gt;<\/span> is that a plain array will decay to a pointer if passed to a function; therefore, the size is lost. This decay is a typical reason for errors in C\/C++.<\/p>\n<h3>Automatically deduces the size of a contiguous sequence of objects<\/h3>\n<p>In contrast, <span style=\"font-family: courier new, courier;\">std<strong>:<\/strong>:span&lt;T&gt;<\/span> automatically deduces the size of contiguous sequences of objects<span style=\"font-family: courier new, courier;\">.<\/span><\/p>\n<p>\u00a0<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ printSpan.cpp<\/span>\n\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;array&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;span&gt;<\/span>\n\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">printMe<\/span>(std<span style=\"color: #555555;\">::<\/span>span<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> container) {\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"container.size(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> container.size() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span>(<span style=\"color: #006699; font-weight: bold;\">auto<\/span> e <span style=\"color: #555555;\">:<\/span> container) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> e <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">' '<\/span>;\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\n}\n\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    \n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> arr[]{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>};              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\n    printMe(arr);\n    \n    std<span style=\"color: #555555;\">::<\/span>vector vec{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>};     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\n    printMe(vec);\n\n    std<span style=\"color: #555555;\">::<\/span>array arr2{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">6<\/span>}; <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\n    printMe(arr2);\n    \n}\n<\/pre>\n<\/div>\n<p>\u00a0<\/p>\n<p>The C-array (1),<span style=\"font-family: courier new, courier;\"> std::vector\u00a0<\/span>(2), and the <span style=\"font-family: courier new, courier;\">std::array<\/span> (3) have <span style=\"font-family: courier new, courier;\">int<\/span>&#8216;s. Consequently, <span style=\"font-family: courier new, courier;\">std::span<\/span> also holds<span style=\"font-family: courier new, courier;\"> int&#8217;<\/span>s. There is something more interesting in this simple example. For each container, <span style=\"font-family: courier new, courier;\">std::span<\/span> can deduce its size (4).<\/p>\n<p>The big three C++ compilers, MSVC, GCC, and Clang, support<span style=\"font-family: courier new, courier;\"> std::span<\/span>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5979\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/printSpan.PNG\" alt=\"printSpan\" width=\"300\" height=\"257\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/printSpan.PNG 327w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/printSpan-300x257.png 300w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>\u00a0<\/p>\n<p>There are more ways to create a <span style=\"font-family: courier new, courier;\">std::span<\/span>.<\/p>\n<h3>Create a std::span from a pointer and a size<\/h3>\n<p>You can create a <span style=\"font-family: courier new, courier;\">std::span<\/span> from a pointer and a size.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ createSpan.cpp<\/span>\n\n<span style=\"color: #009999;\">#include &lt;algorithm&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;span&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\n\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\n\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>boolalpha;\n\n    std<span style=\"color: #555555;\">::<\/span>vector myVec{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>};\n\t\n    std<span style=\"color: #555555;\">::<\/span>span mySpan1{myVec};                                        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\n    std<span style=\"color: #555555;\">::<\/span>span mySpan2{myVec.data(), myVec.size()};                   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\n\t\n    <span style=\"color: #007788; font-weight: bold;\">bool<\/span> spansEqual <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>equal(mySpan1.begin(), mySpan1.end(),\n                                 mySpan2.begin(), mySpan2.end());\n\t\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"mySpan1 == mySpan2: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> spansEqual <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\n\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n\t\n}\n<\/pre>\n<\/div>\n<p>\u00a0<\/p>\n<p>As you may expect, the from a<span style=\"font-family: courier new, courier;\"> std::vector<\/span> created <span style=\"font-family: courier new, courier;\">mySpan1<\/span> (1), and the from a pointer and a size created <span style=\"font-family: courier new, courier;\">mySpan<\/span> (2)\u00a0 are equal (3).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5980\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/createSpan.PNG\" alt=\"createSpan\" width=\"350\" height=\"153\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/createSpan.PNG 354w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/createSpan-300x131.png 300w\" sizes=\"auto, (max-width: 350px) 100vw, 350px\" \/><\/p>\n<p>\u00a0<\/p>\n<p>You may remember that a <span style=\"font-family: courier new, courier;\">std::span <\/span>is sometimes called a view. Don&#8217;t confuse a<span style=\"font-family: courier new, courier;\"> std::span<\/span>\u00a0with a view from the <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-the-ranges-library\">ranges library<\/a>\u00a0(C++20) or a <span style=\"font-family: courier new, courier;\">std::string_view <\/span>(C++17).<\/p>\n<p>A view from the <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-the-ranges-library\">ranges library<\/a> is something that you can apply on a range and performs some operations. A view does not own data, and it&#8217;s time to copy, move, and assignment it&#8217;s constant. Here is a quote from Eric Niebler&#8217;s <a style=\"background-color: transparent; color: #0077bb; text-decoration: none; outline: none;\" href=\"https:\/\/github.com\/ericniebler\/range-v3\">range-v3 implementation<\/a>,\u00a0which is the base for the C++20 ranges: &#8220;<em>Views are composable adaptations of ranges where the adaptation happens lazily as the view is iterated.<\/em>&#8221; These are all my posts to the ranges library: <a href=\"https:\/\/www.modernescpp.com\/index.php\/tag\/ranges-library\">category ranges library<\/a>.\u00a0<\/p>\n<p>A view (<span style=\"font-family: 'courier new', courier;\">std::span<\/span>) and a <span style=\"font-family: 'courier new', courier;\">std::string_view<\/span> are non-owning views and can deal with strings. The main difference between a <span style=\"font-family: courier new, courier;\">std::span<\/span> and a <span style=\"font-family: courier new, courier;\">std::string_view<\/span> is that a <span style=\"font-family: courier new, courier;\">std::span<\/span> can modify its objects. When you want to read more about <span style=\"font-family: courier new, courier;\">std::string_vie<\/span>w, read my previous post: &#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/c-17-what-s-new-in-the-library\">C++17 &#8211; What&#8217;s New in the Library?<\/a>&#8221; and &#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/c-17-avoid-copying-with-std-string-view\">C++17 &#8211; Avoid Copying with<span style=\"font-family: courier new, courier;\"> std::string_view<\/span><\/a>&#8220;.\u00a0<\/p>\n<h3>Modifying its objects<\/h3>\n<p>You can modify the entire span or only a subspan. When you modify the span, you modify the referenced objects.<\/p>\n<p>The following program shows how a subspan can modify the referenced objects from a<span style=\"font-family: courier new, courier;\"> std::vector<\/span>.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ spanTransform.cpp<\/span>\n\n<span style=\"color: #009999;\">#include &lt;algorithm&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;span&gt;<\/span>\n\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">printMe<\/span>(std<span style=\"color: #555555;\">::<\/span>span<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> container) {\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"container.size(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> container.size() <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span>(<span style=\"color: #006699; font-weight: bold;\">auto<\/span> e <span style=\"color: #555555;\">:<\/span> container) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> e <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">' '<\/span>;\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\n}\n\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    \n    std<span style=\"color: #555555;\">::<\/span>vector vec{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">6<\/span>, <span style=\"color: #ff6600;\">7<\/span>, <span style=\"color: #ff6600;\">8<\/span>, <span style=\"color: #ff6600;\">9<\/span>, <span style=\"color: #ff6600;\">10<\/span>};    \n    printMe(vec);\n    \n    std<span style=\"color: #555555;\">::<\/span>span span1(vec);                                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span> \n    std<span style=\"color: #555555;\">::<\/span>span span2{span1.subspan(<span style=\"color: #ff6600;\">1<\/span>, span1.size() <span style=\"color: #555555;\">-<\/span> <span style=\"color: #ff6600;\">2<\/span>)};  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\n    \n                                                 \n    std<span style=\"color: #555555;\">::<\/span>transform(span2.begin(), span2.end(),            <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>  \n                   span2.begin(), \n                   [](<span style=\"color: #007788; font-weight: bold;\">int<\/span> i){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> i <span style=\"color: #555555;\">*<\/span> i; });\n    \n    \n    printMe(vec);                                       \n    \n}\n<\/pre>\n<\/div>\n<p>\u00a0<\/p>\n<p><span style=\"font-family: 'courier new', courier;\">span1<\/span> references the <span style=\"font-family: 'courier new', courier;\">std::vector vec\u00a0<\/span>(1). In contrast, <span style=\"font-family: 'courier new', courier;\">span2<\/span> only references all elements of the underlying <span style=\"font-family: 'courier new', courier;\">vec<\/span> without the first and the last element (2). Consequently, mapping each element to its square (3) only addresses these elements.\u00a0<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5981\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/spanTransform.PNG\" alt=\"spanTransform\" width=\"400\" height=\"241\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/spanTransform.PNG 372w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/spanTransform-300x181.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>There are many convenience functions to refer to the elements of the span.<\/p>\n<h3>Addressing the elements of a\u00a0<span style=\"font-family: 'courier new', courier;\">std::span<\/span><\/h3>\n<p>The table presents the functions to refer to the elements of a span.<\/p>\n<p>\u00a0<\/p>\n<table>\n<tbody>\n<tr>\n<td style=\"border: 1px solid #000000; text-align: center;\"><span style=\"color: #0000ff; font-size: 14pt;\"><strong>Function\u00a0<\/strong><\/span><\/td>\n<td style=\"border: 1px solid #000000; text-align: center;\"><span style=\"color: #0000ff; font-size: 14pt;\"><strong>Description<\/strong><\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #000000;\"><span style=\"font-family: 'courier new', courier;\">\u00a0span.front()<\/span><\/td>\n<td style=\"border: 1px solid #000000;\">Access the first element<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #000000;\"><span style=\"font-family: 'courier new', courier;\">\u00a0span.back()<\/span><\/td>\n<td style=\"border: 1px solid #000000;\">Access the last element<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #000000;\"><span style=\"font-family: 'courier new', courier;\">\u00a0span[i]<\/span><\/td>\n<td style=\"border: 1px solid #000000;\">Access the i-th element<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #000000;\"><span style=\"font-family: 'courier new', courier;\">\u00a0span.data()<\/span><\/td>\n<td style=\"border: 1px solid #000000;\">Returns a pointer to the beginning of the sequence\u00a0<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #000000;\"><span style=\"font-family: 'courier new', courier;\">\u00a0span.size()<\/span><\/td>\n<td style=\"border: 1px solid #000000;\">Returns the number of elements of the sequence<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #000000;\"><span style=\"font-family: 'courier new', courier;\">\u00a0span.size_bytes()<\/span><\/td>\n<td style=\"border: 1px solid #000000;\">Returns the size of the sequence\u00a0<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #000000;\"><span style=\"font-family: 'courier new', courier;\">\u00a0span.empty()<\/span><\/td>\n<td style=\"border: 1px solid #000000;\">Returns if the sequence is empty<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #000000;\">\n<p><span style=\"font-family: 'courier new', courier;\">span&lt;count&gt;.first()<\/span><\/p>\n<p><span style=\"font-family: 'courier new', courier;\">span.first(count)<\/span><\/p>\n<\/td>\n<td style=\"border: 1px solid #000000;\">Returns a subspan consisting of the first <span style=\"font-family: 'courier new', courier;\">count<\/span> elements of the sequence<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #000000;\">\n<p><span style=\"font-family: 'courier new', courier;\">span&lt;count&gt;last()<\/span><\/p>\n<p><span style=\"font-family: 'courier new', courier;\">span.last&lt;count&gt;<\/span><\/p>\n<\/td>\n<td style=\"border: 1px solid #000000;\">Returns a subspan consisting of the last <span style=\"font-family: 'courier new', courier;\">count<\/span> elements of the sequence<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #000000;\">\n<p><span style=\"font-family: 'courier new', courier;\">span&lt;first, count&gt;.subspan()<\/span><\/p>\n<p><span style=\"font-family: 'courier new', courier;\">span.subspan(first, count)<\/span><\/p>\n<\/td>\n<td style=\"border: 1px solid #000000;\">Returns a subspan consisting of <span style=\"font-family: 'courier new', courier;\">count<\/span> elements starting at <span style=\"font-family: 'courier new', courier;\">first<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u00a0<\/p>\n<p>The small program shows the usage of the function <span style=\"font-family: 'courier new', courier;\">subspan<\/span>.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ subspan.cpp<\/span>\n\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;numeric&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;span&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\n\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\n\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n\n    std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> myVec(<span style=\"color: #ff6600;\">20<\/span>);\n    std<span style=\"color: #555555;\">::<\/span>iota(myVec.begin(), myVec.end(), <span style=\"color: #ff6600;\">0<\/span>);                   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> v<span style=\"color: #555555;\">:<\/span> myVec) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> v <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;\n\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\n\n    std<span style=\"color: #555555;\">::<\/span>span<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> mySpan(myVec);                               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> length <span style=\"color: #555555;\">=<\/span> mySpan.size();\n\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> count <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">5<\/span>;                                             <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">long<\/span> <span style=\"color: #007788; font-weight: bold;\">unsigned<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span> first <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span>; first <span style=\"color: #555555;\">&lt;=<\/span> (length <span style=\"color: #555555;\">-<\/span> count); first <span style=\"color: #555555;\">+=<\/span> count ) {\n        <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> ele<span style=\"color: #555555;\">:<\/span> mySpan.subspan(first, count)) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> ele <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;\n        std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    }\n\n}\n<\/pre>\n<\/div>\n<p>\u00a0<\/p>\n<p>The program fills the vector with all numbers from 0 to 19 (1) and initializes a <span style=\"font-family: 'courier new', courier;\">std::span<\/span> with it (2). The algorithm\u00a0<span style=\"font-family: 'courier new', courier;\">std::iota<\/span> fills <span style=\"font-family: 'courier new', courier;\">myVec<\/span> with the\u00a0sequentially increasing values, starting with 0.<span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\"> Finally<\/span>, the for-loop (3) uses the function <span style=\"font-family: 'courier new', courier;\">subspan<\/span> to create all subspans starting at <span style=\"font-family: 'courier new', courier;\">first<\/span> and having <span style=\"font-family: 'courier new', courier;\">count<\/span> elements until <span style=\"font-family: 'courier new', courier;\">mySpan<\/span> is consumed.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5982\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/subspan.PNG\" alt=\"subspan\" width=\"469\" height=\"219\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/subspan.PNG 469w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/subspan-300x140.png 300w\" sizes=\"auto, (max-width: 469px) 100vw, 469px\" \/><\/p>\n<h2>What&#8217;s next?\u00a0<\/h2>\n<p>Containers of the STL become more potent with C++20. For example, a <span style=\"font-family: 'courier new', courier;\">std::string<\/span> and <span style=\"font-family: 'courier new', courier;\">std::vecto<\/span>r can be created and modified at compile-time. Further, thanks to the functions <span style=\"font-family: 'courier new', courier;\">std::erase<\/span> and <span style=\"font-family: 'courier new', courier;\">std::erase_if<\/span>, the deletion of the elements of a container works like a charm.<\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n\n\n\n\n\n\n<p><\/p>\n\n\n\n\n\n\n\n\n\n\n\n\n","protected":false},"excerpt":{"rendered":"<p>In my seminar, I often hear the question: How can I safely pass a plain array to a function? With C++20, the answer is quite easy: Use a std::span.<\/p>\n","protected":false},"author":21,"featured_media":5945,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[456],"class_list":["post-5983","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-20","tag-span"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5983","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5983"}],"version-history":[{"count":2,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5983\/revisions"}],"predecessor-version":[{"id":8905,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5983\/revisions\/8905"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5945"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5983"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5983"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5983"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}