{"id":8906,"date":"2024-01-15T18:56:35","date_gmt":"2024-01-15T18:56:35","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=8906"},"modified":"2024-01-15T18:56:35","modified_gmt":"2024-01-15T18:56:35","slug":"stdspan-in-c20-more-details","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/stdspan-in-c20-more-details\/","title":{"rendered":"std::span in C++20: More Details"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">A<code> std::span<\/code> represents an object that refers to a contiguous sequence of objects. Today, I want to write about its not-so-obvious features.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"955\" height=\"375\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/TimelineCpp20CoreLanguageSpan.png\" alt=\"\" class=\"wp-image-8904\" 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\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">A<code> std::span<\/code>, sometimes also called a view, is never an owner. This contiguous memory can be a plain array, a pointer with a size, a <code>std::array<\/code>, a <code>std::vector<\/code>, or a <code>std::string<\/code>. A typical implementation consists of a pointer to its first element and a size. The main reason for having a<code> std::span&lt;T&gt; <\/code>is that a plain array will decay to a pointer if passed to a function; therefore, the size is lost. This <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/decay\" data-type=\"link\" data-id=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/decay\">decay<\/a> is a typical reason for errors in C\/C++.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Automatically deduces the size of a contiguous sequence of objects<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In contrast,<code> std<strong>:<\/strong>:span&lt;T&gt; <\/code>automatically deduces the size of contiguous sequences of objects.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><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\">&quot;container.size(): &quot;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> container.size() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/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\">&#39; &#39;<\/span>;\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n\\n<\/span><span style=\"color: #CC3300\">&quot;<\/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><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The C-array (1),<code> std::vector<\/code>&nbsp;(2), and the <code>std::array<\/code> (3) have<code> int<\/code>\u2018s. Consequently,<code> std::span<\/code> also holds <code>int<\/code>\u2019s. There is something more interesting in this simple example. For each container,<code> std::span<\/code> can deduce its size (4).<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"327\" height=\"280\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/printSpan.png\" alt=\"\" class=\"wp-image-8908\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/printSpan.png 327w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/printSpan-300x257.png 300w\" sizes=\"auto, (max-width: 327px) 100vw, 327px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This was a short reminder about <code>std::span<\/code>. For the full story, read my previous post &#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-std-span\/\" data-type=\"link\" data-id=\"https:\/\/www.modernescpp.com\/index.php\/c-20-std-span\/\">std::span in C++20: Bounds-Safe Views of Sequences of Objects<\/a>&#8220;.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A<code> std::span<\/code> can have a static extent or a dynamic extent. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Static versus Dynamic Extent<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">By default, <code>std::span<\/code> has a dynamic extent:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #006699; font-weight: bold\">template<\/span> <span style=\"color: #555555\">&lt;<\/span><span style=\"color: #006699; font-weight: bold\">typename<\/span> T, std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> Extent <span style=\"color: #555555\">=<\/span> std<span style=\"color: #555555\">::<\/span>dynamic_extent<span style=\"color: #555555\">&gt;<\/span>\n<span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">span<\/span>;\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">When a<code> std::span<\/code> has a <em><strong>static extent<\/strong><\/em>, its size is known at compile time and part of the type:<code> std::span<\/code>. Consequently, its implementation needs only a pointer to the first element of the contiguous sequence of objects.<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Implementing a<code> std::span<\/code> with a <strong><em>dynamic extent <\/em><\/strong>consists of a pointer to the first element and the size of the contiguous sequence of objects. The size is not part of the <code>std::span<\/code> type.<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The next example emphasizes the differences between the two kinds of spans.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ staticDynamicExtentSpan.cpp<\/span>\n\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\">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) {        <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> <span style=\"color: #CC3300\">&quot;container.size(): &quot;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> container.size() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/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\">&#39; &#39;<\/span>;\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n\\n<\/span><span style=\"color: #CC3300\">&quot;<\/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> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n    std<span style=\"color: #555555\">::<\/span>vector myVec1{<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    std<span style=\"color: #555555\">::<\/span>vector myVec2{<span style=\"color: #FF6600\">6<\/span>, <span style=\"color: #FF6600\">7<\/span>, <span style=\"color: #FF6600\">8<\/span>, <span style=\"color: #FF6600\">9<\/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> dynamicSpan(myVec1);          <span style=\"color: #0099FF; font-style: italic\">\/\/ (1)<\/span>\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: #FF6600\">4<\/span><span style=\"color: #555555\">&gt;<\/span> staticSpan(myVec2);        <span style=\"color: #0099FF; font-style: italic\">\/\/ (2)<\/span>\n\n    printMe(dynamicSpan);\n    printMe(staticSpan);\n\n    <span style=\"color: #0099FF; font-style: italic\">\/\/ staticSpan = dynamicSpan;    ERROR        \/\/ (4)<\/span>\n    dynamicSpan <span style=\"color: #555555\">=<\/span> staticSpan;                    <span style=\"color: #0099FF; font-style: italic\">\/\/ (5) <\/span>\n\n    printMe(staticSpan);                         <span style=\"color: #0099FF; font-style: italic\">\/\/ (6)<\/span>\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n    \n}\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><code>dynamicSpan<\/code> (line 1) has a dynamic extent, while <code>staticSpan<\/code> (line 2) has a static extent. Both<code> std::span<\/code>s return their size in the <code>printMe<\/code> function (line 3). A <code>std::span <\/code>with static extent can be assigned to a <code>std::span<\/code> with dynamic extent, but not vice versa. Line 4 would cause an error, but lines 5, and 6 are valid.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"529\" height=\"362\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/staticDynamicExtentSpan.png\" alt=\"\" class=\"wp-image-8915\" style=\"width:400px\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/staticDynamicExtentSpan.png 529w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/staticDynamicExtentSpan-300x205.png 300w\" sizes=\"auto, (max-width: 529px) 100vw, 529px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">There is one particular use case of <code>std::span<\/code>.  A<code> std::span<\/code> can be a constant range of modifiable elements.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Constant Range of Modifiable Elements<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For simplicity, I name a<code> std::vector<\/code> and a <code>std::span range<\/code>. A <code>std::vector<\/code> models a modifiable range of modifiable elements:<code> std::vector<\/code>. When you declare this<code> std::vector<\/code> as <code>const<\/code>, it models a constant range of constant objects:<code> const std::vector<\/code>. You cannot model a constant range of modifiable elements. This is where<code> std::span<\/code> comes into play. A <code>std::span<\/code> models a constant range of modifiable objects: <code>std::span<\/code>. The following image emphasizes the variations of (constant\/modifiable) ranges and (constant\/modifiable) elements.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"779\" height=\"176\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/constRange.png\" alt=\"\" class=\"wp-image-8919\" style=\"width:600px\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/constRange.png 779w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/constRange-300x68.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/constRange-768x174.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/constRange-705x159.png 705w\" sizes=\"auto, (max-width: 779px) 100vw, 779px\" \/><\/figure>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ constRangeModifiableElements.cpp<\/span>\n\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\">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\">&quot;container.size(): &quot;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> container.size() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/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\">&#39; &#39;<\/span>;\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n\\n<\/span><span style=\"color: #CC3300\">&quot;<\/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> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\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> origVec{<span style=\"color: #FF6600\">1<\/span>, <span style=\"color: #FF6600\">2<\/span>, <span style=\"color: #FF6600\">2<\/span>, <span style=\"color: #FF6600\">4<\/span>, <span style=\"color: #FF6600\">5<\/span>};\n\n    <span style=\"color: #0099FF; font-style: italic\">\/\/ Modifiable range of modifiable elements<\/span>\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> dynamVec <span style=\"color: #555555\">=<\/span> origVec;           <span style=\"color: #0099FF; font-style: italic\">\/\/ (1)<\/span>\n    dynamVec[<span style=\"color: #FF6600\">2<\/span>] <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">3<\/span>;\n    dynamVec.push_back(<span style=\"color: #FF6600\">6<\/span>);\n    printMe(dynamVec);\n\n    <span style=\"color: #0099FF; font-style: italic\">\/\/ Constant range of constant elements<\/span>\n    <span style=\"color: #006699; font-weight: bold\">const<\/span> std<span style=\"color: #555555\">::<\/span>vector<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> constVec <span style=\"color: #555555\">=<\/span> origVec;     <span style=\"color: #0099FF; font-style: italic\">\/\/ (2)<\/span>\n    <span style=\"color: #0099FF; font-style: italic\">\/\/ constVec[2] = 3;        ERROR<\/span>\n    <span style=\"color: #0099FF; font-style: italic\">\/\/ constVec.push_back(6);  ERROR<\/span>\n    std<span style=\"color: #555555\">::<\/span>span<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #006699; font-weight: bold\">const<\/span> <span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> constSpan(origVec);       <span style=\"color: #0099FF; font-style: italic\">\/\/ (3)<\/span>\n    <span style=\"color: #0099FF; font-style: italic\">\/\/ constSpan[2] = 3;       ERROR<\/span>\n\n    <span style=\"color: #0099FF; font-style: italic\">\/\/ Constant range of modifiable elements<\/span>\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> dynamSpan{origVec};             <span style=\"color: #0099FF; font-style: italic\">\/\/ (4)<\/span>\n    dynamSpan[<span style=\"color: #FF6600\">2<\/span>] <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">3<\/span>;\n    printMe(dynamSpan);\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n}\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The vector <code>dynamVec<\/code> (line 1) is a modifiable range of modifiable elements. This observation does not hold for the vector <code>constVec<\/code> (line 2). Neither can <code>constVec<\/code> change its elements nor its size. <code>constSpan<\/code> (line 3) behaves accordingly. <code>dynamSpan<\/code> (line 4) models the unique use case of a constant range of modifiable elements.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"578\" height=\"292\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/constRangeModifiableElements.png\" alt=\"\" class=\"wp-image-8922\" style=\"width:500px\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/constRangeModifiableElements.png 578w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/constRangeModifiableElements-300x152.png 300w\" sizes=\"auto, (max-width: 578px) 100vw, 578px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, I want to mention two dangers you should know when using <code>std::span<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dangers of <code>std::span<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The typical issues of <code>std::span<\/code> are twofold. First, a <code>std::span<\/code> should not act on a temporary and second, the size of the underlying contiguous range of a<code> std::span<\/code> should not be modified.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">A <code>std::span<\/code> on a Temporary<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A <code>std::span<\/code> is never an owner. Therefore, a <code>std::span<\/code> does not extend the lifetime of its underlying data. Consequently, a std::span should only operate on an lvalue. Using  <code>std::span<\/code> on a temporary range is undefined behavior.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ temporarySpan.cpp<\/span>\n\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\nstd<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> getVector() {                          <span style=\"color: #0099FF; font-style: italic\">\/\/ (2)<\/span>\n    <span style=\"color: #006699; font-weight: bold\">return<\/span> {<span style=\"color: #FF6600\">1<\/span>, <span style=\"color: #FF6600\">2<\/span>, <span style=\"color: #FF6600\">3<\/span>, <span style=\"color: #FF6600\">4<\/span>, <span style=\"color: #FF6600\">5<\/span>};\n}\n\n<span style=\"color: #007788; font-weight: bold\">int<\/span> main() {\n\n     std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\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\">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\">\/\/ (1)<\/span>\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: #FF6600\">5<\/span><span style=\"color: #555555\">&gt;<\/span> mySpan1{myVec};                  \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: #FF6600\">5<\/span><span style=\"color: #555555\">&gt;<\/span> mySpan2{getVector().begin(), <span style=\"color: #FF6600\">5<\/span>};  <span style=\"color: #0099FF; font-style: italic\">\/\/ (3)<\/span>\n\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> std<span style=\"color: #555555\">::<\/span>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\">&quot; &quot;<\/span>;\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/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> std<span style=\"color: #555555\">::<\/span>span{getVector().begin(), <span style=\"color: #FF6600\">5<\/span>}) 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\">&quot; &quot;<\/span>;  <span style=\"color: #0099FF; font-style: italic\">\/\/ (4)<\/span>\n\n     std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;<\/span><span style=\"color: #CC3300; font-weight: bold\">\\n\\n<\/span><span style=\"color: #CC3300\">&quot;<\/span>;\n    \n}\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Using a <code>std::span<\/code> with a static extent or a <code>std::span<\/code> with a dynamic extent on the lvalue is fine. When I switch from the lvalue <code>std::vector<\/code> in line 1 to a temporary<code> std::vector<\/code>, given by the function <code>getVector<\/code> (lines 2), the program has undefined behavior. Both lines 3 and 4 are not valid. Consequently, executing the program exposes the undefined behavior. The output of line 4 does not match with the <code>std::vector<\/code>, generated by the function <code>getVector().<\/code><\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"393\" height=\"237\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/temporarySpan.png\" alt=\"\" class=\"wp-image-8956\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/temporarySpan.png 393w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/01\/temporarySpan-300x181.png 300w\" sizes=\"auto, (max-width: 393px) 100vw, 393px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Changing the Size of the Underlying Contiguous Range<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When you change the size of the underlying contiguous range, the contiguous range may be reallocated, and the <code>std::span<\/code> refers to stale data. <\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\">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\">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\nstd<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> sp1{myVec};\n\nmyVec.push_back(<span style=\"color: #FF6600\">6<\/span>);  <span style=\"color: #0099FF; font-style: italic\">\/\/ undefined behavior<\/span>\n<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s Next?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In my next post, I dive once more in the formatting library of C++20.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A std::span represents an object that refers to a contiguous sequence of objects. Today, I want to write about its not-so-obvious features. A std::span, sometimes also called a view, is never an owner. This contiguous memory can be a plain array, a pointer with a size, a std::array, a std::vector, or a std::string. A typical [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":8904,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[456],"class_list":["post-8906","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\/8906","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=8906"}],"version-history":[{"count":19,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/8906\/revisions"}],"predecessor-version":[{"id":8957,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/8906\/revisions\/8957"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/8904"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=8906"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=8906"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=8906"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}