{"id":445,"date":"2023-06-11T22:39:53","date_gmt":"2023-06-11T22:39:53","guid":{"rendered":"https:\/\/www.w3computing.com\/articles\/?p=445"},"modified":"2023-08-23T16:21:47","modified_gmt":"2023-08-23T16:21:47","slug":"using-stdspan-cpp20-practical-guide","status":"publish","type":"post","link":"https:\/\/www.w3computing.com\/articles\/using-stdspan-cpp20-practical-guide\/","title":{"rendered":"Using std::span in C++20: A Practical Guide"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">C++, a language known for its performance and efficiency. With each new standard release, it offers more features and tools that make coding in it more robust and convenient. One such tool, introduced in C++20, is <code><strong>std::span<\/strong><\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this practical guide, we will delve into <code><strong>std::span<\/strong><\/code> and its utility in contemporary C++ programming. This lightweight, non-owning reference to an array or a part of an array has the potential to streamline your code, reducing redundancy and enhancing clarity.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Whether you&#8217;re working with arrays, vectors, or other data structures, <code><strong>std::span<\/strong><\/code> can be a versatile tool in your C++ toolbox. It bridges the gap between dynamic and static containers, providing a degree of flexibility that C++ programmers have long sought.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Through the course of this article, we will explore what <code><strong>std::span<\/strong><\/code> is, why it&#8217;s a valuable addition to C++20, and how to use it effectively in your code. This guide is packed with real-world examples to help you grasp the concept and start applying it in your own projects.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Basics of <code>std::span<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To appreciate the value <code><strong>std::span<\/strong><\/code> brings to C++20, we first need to understand its definition and purpose. At its core, <code><strong>std::span<\/strong><\/code> is a simple tool designed to enhance the way we handle data sequences in C++.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code><strong>std::span<\/strong><\/code> is a lightweight, non-owning reference to a sequence &#8211; be it an array or a part of an array. The term &#8216;non-owning&#8217; is crucial here. It implies that <code><strong>std::span<\/strong><\/code> does not manage the lifetime of the objects it refers to. Instead, it merely provides a view or a reference to an existing sequence of data. This feature makes <code><strong>std::span<\/strong><\/code> an efficient tool for passing around views of contiguous sequences (like arrays) without having to copy or clone them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s also worth noting that <code><strong>std::span<\/strong><\/code> is not restricted to static arrays. It can work with dynamic data structures like <code><strong>std::vector<\/strong><\/code> and <code><strong>std::array<\/strong><\/code>, making it a highly versatile tool that works seamlessly with both dynamic and static containers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In essence, <code><strong>std::span<\/strong><\/code> serves as a bridge between dynamic and static worlds, offering a unified, efficient way to handle data sequences in C++. It&#8217;s a testament to the C++ ethos of zero-overhead abstraction &#8211; you get a high-level view of your data without sacrificing performance.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating and Initializing <code>std::span<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Creating and initializing <code><strong>std::span<\/strong><\/code> is straightforward and intuitive. To define a <code><strong>std::span<\/strong><\/code>, you need to provide the type of elements the <code><strong>std::span<\/strong><\/code> will reference and optionally the extent of the <code><strong>std::span<\/strong><\/code>, which is the number of elements it can hold.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here is a basic example of defining a <code><strong>std::span<\/strong><\/code>:<\/p>\n\n\n<pre class=\"wp-block-code lang-cpp\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-built_in\">std<\/span>::span&lt;<span class=\"hljs-keyword\">int<\/span>&gt; my_span;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this case, <code>my_span<\/code> is a <code>std::span<\/code> that refers to a sequence of <code>int<\/code> elements. Note that at this point, <code>my_span<\/code> doesn&#8217;t yet reference any actual data.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To initialize a <code>std::span<\/code>, you can use an array, a pointer with a size, two pointers, or a container like <code>std::vector<\/code> or <code>std::array<\/code>. Let&#8217;s take a look at some examples:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Initializing with an array:<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-keyword\">int<\/span> my_array&#91;<span class=\"hljs-number\">5<\/span>] = {<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>, <span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">5<\/span>};\n<span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::span&lt;<span class=\"hljs-keyword\">int<\/span>&gt; <span class=\"hljs-title\">span_from_array<\/span><span class=\"hljs-params\">(my_array)<\/span><\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Initializing with two pointers:<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-keyword\">int<\/span> my_array&#91;<span class=\"hljs-number\">5<\/span>] = {<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>, <span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">5<\/span>};\n<span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::span&lt;<span class=\"hljs-keyword\">int<\/span>&gt; <span class=\"hljs-title\">span_from_pointers<\/span><span class=\"hljs-params\">(&amp;my_array&#91;<span class=\"hljs-number\">0<\/span>], &amp;my_array&#91;<span class=\"hljs-number\">4<\/span>])<\/span><\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Initializing with a pointer and size:<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-keyword\">int<\/span> my_array&#91;<span class=\"hljs-number\">5<\/span>] = {<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>, <span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">5<\/span>};\n<span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::span&lt;<span class=\"hljs-keyword\">int<\/span>&gt; <span class=\"hljs-title\">span_from_pointer_and_size<\/span><span class=\"hljs-params\">(my_array, <span class=\"hljs-number\">5<\/span>)<\/span><\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Initializing with a container:<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-keyword\">int<\/span>&gt; my_vector = {<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>, <span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">5<\/span>};\n<span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::span&lt;<span class=\"hljs-keyword\">int<\/span>&gt; <span class=\"hljs-title\">span_from_vector<\/span><span class=\"hljs-params\">(my_vector)<\/span><\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Remember, <code>std::span<\/code> does not own the data it refers to. So if the data it points to is destroyed or goes out of scope, the <code>std::span<\/code> will be left dangling. Always be mindful of the lifetime of your data when working with <code>std::span<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Accessing Elements in <code>std::span<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Just like with other containers in C++, you can easily access the elements in a <code>std::span<\/code>. You can use the array subscript operator (<code>[]<\/code>) or the <code>at()<\/code> member function, similar to how you would with an array or <code>std::vector<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s how you might do it:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-keyword\">int<\/span>&gt; my_vector = {<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>, <span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">5<\/span>};\n<span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::span&lt;<span class=\"hljs-keyword\">int<\/span>&gt; <span class=\"hljs-title\">my_span<\/span><span class=\"hljs-params\">(my_vector)<\/span><\/span>;\n\n<span class=\"hljs-comment\">\/\/ Accessing elements<\/span>\n<span class=\"hljs-keyword\">int<\/span> first_element = my_span&#91;<span class=\"hljs-number\">0<\/span>];\n<span class=\"hljs-keyword\">int<\/span> second_element = my_span.at(<span class=\"hljs-number\">1<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Note that while the array subscript operator (<code>[]<\/code>) does not perform bounds checking, the <code>at()<\/code> function does and will throw an exception (<code>std::out_of_range<\/code>) if you attempt to access an element outside the valid range.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In addition to accessing individual elements, <code>std::span<\/code> provides several utility functions to work with the sequence:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>size()<\/code>: Returns the number of elements in the <code>std::span<\/code>.<\/li>\n\n\n\n<li><code>length()<\/code>: This is an alias for <code>size()<\/code>. It also returns the number of elements in the <code>std::span<\/code>.<\/li>\n\n\n\n<li><code>empty()<\/code>: Checks if the <code>std::span<\/code> is empty (i.e., whether its size is 0).<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-keyword\">int<\/span>&gt; my_vector = {<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>, <span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">5<\/span>};\n<span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::span&lt;<span class=\"hljs-keyword\">int<\/span>&gt; <span class=\"hljs-title\">my_span<\/span><span class=\"hljs-params\">(my_vector)<\/span><\/span>;\n\n<span class=\"hljs-comment\">\/\/ Using utility functions<\/span>\n<span class=\"hljs-keyword\">size_t<\/span> num_elements = my_span.size(); <span class=\"hljs-comment\">\/\/ returns 5<\/span>\n<span class=\"hljs-keyword\">bool<\/span> is_empty = my_span.empty(); <span class=\"hljs-comment\">\/\/ returns false<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Manipulating <code>std::span<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><code>std::span<\/code> is a versatile tool, not just for accessing elements, but also for manipulating the viewed sequence. It offers several functions that allow us to create subviews of the original sequence, essentially providing us with slices of our data. These functions include <code>first()<\/code>, <code>last()<\/code>, and <code>subspan()<\/code>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>first(count)<\/code>: Creates a new <code>std::span<\/code> that covers the first <code>count<\/code> elements of the original <code>std::span<\/code>.<\/li>\n\n\n\n<li><code>last(count)<\/code>: Creates a new <code>std::span<\/code> that covers the last <code>count<\/code> elements of the original <code>std::span<\/code>.<\/li>\n\n\n\n<li><code>subspan(offset, count)<\/code>: Creates a new <code>std::span<\/code> that starts from the <code>offset<\/code> and spans <code>count<\/code> elements of the original <code>std::span<\/code>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Here are some examples of these functions in action:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-keyword\">int<\/span>&gt; my_vector = {<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>, <span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">5<\/span>, <span class=\"hljs-number\">6<\/span>, <span class=\"hljs-number\">7<\/span>, <span class=\"hljs-number\">8<\/span>, <span class=\"hljs-number\">9<\/span>, <span class=\"hljs-number\">10<\/span>};\n<span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::span&lt;<span class=\"hljs-keyword\">int<\/span>&gt; <span class=\"hljs-title\">my_span<\/span><span class=\"hljs-params\">(my_vector)<\/span><\/span>;\n\n<span class=\"hljs-comment\">\/\/ Using first() to create a subspan<\/span>\n<span class=\"hljs-built_in\">std<\/span>::span&lt;<span class=\"hljs-keyword\">int<\/span>&gt; first_half = my_span.first(<span class=\"hljs-number\">5<\/span>); <span class=\"hljs-comment\">\/\/ Contains {1, 2, 3, 4, 5}<\/span>\n\n<span class=\"hljs-comment\">\/\/ Using last() to create a subspan<\/span>\n<span class=\"hljs-built_in\">std<\/span>::span&lt;<span class=\"hljs-keyword\">int<\/span>&gt; last_half = my_span.last(<span class=\"hljs-number\">5<\/span>); <span class=\"hljs-comment\">\/\/ Contains {6, 7, 8, 9, 10}<\/span>\n\n<span class=\"hljs-comment\">\/\/ Using subspan() to create a subspan<\/span>\n<span class=\"hljs-built_in\">std<\/span>::span&lt;<span class=\"hljs-keyword\">int<\/span>&gt; middle = my_span.subspan(<span class=\"hljs-number\">3<\/span>, <span class=\"hljs-number\">4<\/span>); <span class=\"hljs-comment\">\/\/ Contains {4, 5, 6, 7}<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Remember, these subspans are just views of the original data. They don&#8217;t own the data they&#8217;re viewing, and they don&#8217;t copy or move anything around. This makes these operations extremely efficient.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using <code>std::span<\/code> with Other STL Containers<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">One of the great benefits of <code>std::span<\/code> is its ability to work seamlessly with other Standard Template Library (STL) containers. You can initialize a <code>std::span<\/code> with any STL container that provides contiguous storage, like <code>std::vector<\/code> or <code>std::array<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here are some examples:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-comment\">\/\/ With std::vector<\/span>\n<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-keyword\">int<\/span>&gt; my_vector = {<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>, <span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">5<\/span>};\n<span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::span&lt;<span class=\"hljs-keyword\">int<\/span>&gt; <span class=\"hljs-title\">span_from_vector<\/span><span class=\"hljs-params\">(my_vector)<\/span><\/span>;\n\n<span class=\"hljs-comment\">\/\/ With std::array<\/span>\n<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">array<\/span>&lt;<span class=\"hljs-keyword\">int<\/span>, 5&gt; my_array = {<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>, <span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">5<\/span>};\n<span class=\"hljs-function\"><span class=\"hljs-built_in\">std<\/span>::span&lt;<span class=\"hljs-keyword\">int<\/span>&gt; <span class=\"hljs-title\">span_from_array<\/span><span class=\"hljs-params\">(my_array)<\/span><\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In these examples, <code>span_from_vector<\/code> and <code>span_from_array<\/code> provide a view of the data stored in <code>my_vector<\/code> and <code>my_array<\/code>, respectively. You can then use this <code>std::span<\/code> to access and manipulate the data in a unified manner, regardless of whether the underlying container is a <code>std::vector<\/code> or a <code>std::array<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This unified access is one of the key strengths of <code>std::span<\/code>. It allows you to write generic code that operates on a sequence of data, without caring about the specific type of the underlying container. This can greatly enhance the reusability and flexibility of your code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using <code>std::span<\/code> in Functions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A common use case for <code>std::span<\/code> is as function parameters. When a function needs to operate on a sequence of data, it can take a <code>std::span<\/code> as a parameter. This allows the function to be agnostic about the type of container that stores the data, as long as it provides contiguous storage.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is advantageous for several reasons:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Flexibility<\/strong>: The function can accept any type of container (like <code>std::array<\/code>, <code>std::vector<\/code>, or even a C-style array), enhancing its reusability.<\/li>\n\n\n\n<li><strong>Efficiency<\/strong>: As <code>std::span<\/code> does not own the data it points to and does not involve any deep copying, it&#8217;s a lightweight and efficient way of passing around views of data.<\/li>\n\n\n\n<li><strong>Clarity<\/strong>: By using <code>std::span<\/code>, you signal to the readers of your code that the function does not take ownership of the data and does not modify its lifetime.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of a function that takes a <code>std::span<\/code> as a parameter:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"C++\" data-shcb-language-slug=\"cpp\"><span><code class=\"hljs language-cpp\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">print_elements<\/span><span class=\"hljs-params\">(<span class=\"hljs-built_in\">std<\/span>::span&lt;<span class=\"hljs-keyword\">int<\/span>&gt; numbers)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> number : numbers) {\n        <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; number &lt;&lt; <span class=\"hljs-string\">\" \"<\/span>;\n    }\n    <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">cout<\/span> &lt;&lt; <span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">endl<\/span>;\n}\n\n<span class=\"hljs-comment\">\/\/ Usage with different containers:<\/span>\n<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">vector<\/span>&lt;<span class=\"hljs-keyword\">int<\/span>&gt; my_vector = {<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>, <span class=\"hljs-number\">4<\/span>, <span class=\"hljs-number\">5<\/span>};\nprint_elements(my_vector); <span class=\"hljs-comment\">\/\/ Can pass std::vector<\/span>\n\n<span class=\"hljs-built_in\">std<\/span>::<span class=\"hljs-built_in\">array<\/span>&lt;<span class=\"hljs-keyword\">int<\/span>, 5&gt; my_array = {<span class=\"hljs-number\">6<\/span>, <span class=\"hljs-number\">7<\/span>, <span class=\"hljs-number\">8<\/span>, <span class=\"hljs-number\">9<\/span>, <span class=\"hljs-number\">10<\/span>};\nprint_elements(my_array); <span class=\"hljs-comment\">\/\/ Can pass std::array<\/span>\n\n<span class=\"hljs-keyword\">int<\/span> my_c_array&#91;<span class=\"hljs-number\">5<\/span>] = {<span class=\"hljs-number\">11<\/span>, <span class=\"hljs-number\">12<\/span>, <span class=\"hljs-number\">13<\/span>, <span class=\"hljs-number\">14<\/span>, <span class=\"hljs-number\">15<\/span>};\nprint_elements(my_c_array); <span class=\"hljs-comment\">\/\/ Can pass C-style array<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C++<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cpp<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Safety Considerations and Limitations of <code>std::span<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">While <code>std::span<\/code> is a powerful tool, it&#8217;s important to remember the safety considerations and limitations that come with it.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Safety Considerations<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The main safety concern with <code>std::span<\/code> is its non-owning nature. <code>std::span<\/code> provides a view into a sequence of data but does not own or manage the lifetime of that data. This means that if the original data is modified or destroyed while a <code>std::span<\/code> is still pointing to it, the <code>std::span<\/code> will be left dangling. This can lead to undefined behavior and hard-to-track bugs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore, it&#8217;s crucial to always be mindful of the lifetime of your data when working with <code>std::span<\/code>. Avoid returning <code>std::span<\/code> from functions if there&#8217;s any chance that the data it points to could go out of scope.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Limitations<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>std::span<\/code> can only handle sequences that provide contiguous storage. This means it can work with arrays, <code>std::array<\/code>, <code>std::vector<\/code>, and similar containers, but not with containers like <code>std::list<\/code> or <code>std::map<\/code> that do not guarantee contiguous storage.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Furthermore, <code>std::span<\/code> is not designed to replace other STL containers. It lacks features like memory management, dynamic resizing, or element insertion and deletion. Instead, <code>std::span<\/code> is meant to complement these containers, providing a lightweight and efficient way to view and pass around their data.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>C++, a language known for its performance and efficiency. With each new standard release, it offers more features and tools that make coding in it more robust and convenient. One such tool, introduced in C++20, is std::span. In this practical guide, we will delve into std::span and its utility in contemporary C++ programming. This lightweight, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[9,4],"tags":[],"class_list":["post-445","post","type-post","status-publish","format-standard","category-cplusplus","category-programming-languages","entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Using std::span in C++20: A Practical Guide<\/title>\n<meta name=\"description\" content=\"Discover how to use std::span in C++20 with our detailed, practical guide. With code examples and clear explanations\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.w3computing.com\/articles\/using-stdspan-cpp20-practical-guide\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using std::span in C++20: A Practical Guide\" \/>\n<meta property=\"og:description\" content=\"Discover how to use std::span in C++20 with our detailed, practical guide. With code examples and clear explanations\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.w3computing.com\/articles\/using-stdspan-cpp20-practical-guide\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-06-11T22:39:53+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-08-23T16:21:47+00:00\" \/>\n<meta name=\"author\" content=\"w3compadmin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"w3compadmin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/using-stdspan-cpp20-practical-guide\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/using-stdspan-cpp20-practical-guide\\\/\"},\"author\":{\"name\":\"w3compadmin\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"headline\":\"Using std::span in C++20: A Practical Guide\",\"datePublished\":\"2023-06-11T22:39:53+00:00\",\"dateModified\":\"2023-08-23T16:21:47+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/using-stdspan-cpp20-practical-guide\\\/\"},\"wordCount\":1240,\"commentCount\":0,\"articleSection\":[\"C++\",\"Programming Languages\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/using-stdspan-cpp20-practical-guide\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/using-stdspan-cpp20-practical-guide\\\/\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/using-stdspan-cpp20-practical-guide\\\/\",\"name\":\"Using std::span in C++20: A Practical Guide\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\"},\"datePublished\":\"2023-06-11T22:39:53+00:00\",\"dateModified\":\"2023-08-23T16:21:47+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"description\":\"Discover how to use std::span in C++20 with our detailed, practical guide. With code examples and clear explanations\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/using-stdspan-cpp20-practical-guide\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/using-stdspan-cpp20-practical-guide\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/using-stdspan-cpp20-practical-guide\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Articles Home\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Programming Languages\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/programming-languages\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Using std::span in C++20: A Practical Guide\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\",\"name\":\"Developer Articles Hub\",\"description\":\"\",\"alternateName\":\"Developer Articles\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\",\"name\":\"w3compadmin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167\",\"contentUrl\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167\",\"caption\":\"w3compadmin\"},\"sameAs\":[\"http:\\\/\\\/w3computing.com\\\/articles\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using std::span in C++20: A Practical Guide","description":"Discover how to use std::span in C++20 with our detailed, practical guide. With code examples and clear explanations","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.w3computing.com\/articles\/using-stdspan-cpp20-practical-guide\/","og_locale":"en_US","og_type":"article","og_title":"Using std::span in C++20: A Practical Guide","og_description":"Discover how to use std::span in C++20 with our detailed, practical guide. With code examples and clear explanations","og_url":"https:\/\/www.w3computing.com\/articles\/using-stdspan-cpp20-practical-guide\/","article_published_time":"2023-06-11T22:39:53+00:00","article_modified_time":"2023-08-23T16:21:47+00:00","author":"w3compadmin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"w3compadmin","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.w3computing.com\/articles\/using-stdspan-cpp20-practical-guide\/#article","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/using-stdspan-cpp20-practical-guide\/"},"author":{"name":"w3compadmin","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"headline":"Using std::span in C++20: A Practical Guide","datePublished":"2023-06-11T22:39:53+00:00","dateModified":"2023-08-23T16:21:47+00:00","mainEntityOfPage":{"@id":"https:\/\/www.w3computing.com\/articles\/using-stdspan-cpp20-practical-guide\/"},"wordCount":1240,"commentCount":0,"articleSection":["C++","Programming Languages"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.w3computing.com\/articles\/using-stdspan-cpp20-practical-guide\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.w3computing.com\/articles\/using-stdspan-cpp20-practical-guide\/","url":"https:\/\/www.w3computing.com\/articles\/using-stdspan-cpp20-practical-guide\/","name":"Using std::span in C++20: A Practical Guide","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/#website"},"datePublished":"2023-06-11T22:39:53+00:00","dateModified":"2023-08-23T16:21:47+00:00","author":{"@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"description":"Discover how to use std::span in C++20 with our detailed, practical guide. With code examples and clear explanations","breadcrumb":{"@id":"https:\/\/www.w3computing.com\/articles\/using-stdspan-cpp20-practical-guide\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.w3computing.com\/articles\/using-stdspan-cpp20-practical-guide\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.w3computing.com\/articles\/using-stdspan-cpp20-practical-guide\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Articles Home","item":"https:\/\/www.w3computing.com\/articles\/"},{"@type":"ListItem","position":2,"name":"Programming Languages","item":"https:\/\/www.w3computing.com\/articles\/programming-languages\/"},{"@type":"ListItem","position":3,"name":"Using std::span in C++20: A Practical Guide"}]},{"@type":"WebSite","@id":"https:\/\/www.w3computing.com\/articles\/#website","url":"https:\/\/www.w3computing.com\/articles\/","name":"Developer Articles Hub","description":"","alternateName":"Developer Articles","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.w3computing.com\/articles\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561","name":"w3compadmin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167","url":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167","contentUrl":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167","caption":"w3compadmin"},"sameAs":["http:\/\/w3computing.com\/articles"]}]}},"featured_image_src":null,"featured_image_src_square":null,"author_info":{"display_name":"w3compadmin","author_link":"https:\/\/www.w3computing.com\/articles\/author\/w3compadmin\/"},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/445","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/comments?post=445"}],"version-history":[{"count":11,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/445\/revisions"}],"predecessor-version":[{"id":485,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/445\/revisions\/485"}],"wp:attachment":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/media?parent=445"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/categories?post=445"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/tags?post=445"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}