Go learn about std::span

Hello everyone! Today I’d like to highlight something magical: std::span.


What is std::span ?

Simply put std::span is a pointer and a size.

Another way to think about is std::span is to std::vector the same way as std::string_view is to std::string.

Any time you need to observe/view some contigious data it’s preferable to use an std::span over something like std::vector & or const std::vector &.

This gives you nice copy properties and abstracts away the containing object.

I love using const to improve the reliability of code. span is a natural extention of that because now the entire containing object is considered constant because users of the span have no indication of what the containing object is.

In theory span should also help with better cache locality also since you’re only loading the data and entirely avoiding the container’s data.

Ownership also plays a part here, say you want the user to pass in a set of elements and you’re going to modify them but want to make it clear you won’t add or delete any. std::span<int> retains the ability to modify the elements but not the surrounding structure.


How do you use it?

A simple example of how to use this code is say you’d like to find the minimum of an unsorted array. You might write that code in the following way:

#include <iostream>
#include <vector>

template<typename T>
T min(const std::vector<T> & data)
{
  T ret = data.front();
  for(int i = 1; i < data.size(); i++)
  {
    if(data[i] < ret)
      ret = data[i];
  }
  return ret;
}

int main(void)
{
  const std::vector<int> data{64, 89, 21, 64, 98, 03, 26, 90, 48, 30, 92, 14, 98, 32, 17};
  std::cout << min(data) << std::endl;
  return 0;
}

Instead you’d write:

#include <iostream>
#include <span>
#include <vector>

template<typename T>
T min(std::span<const T> data)
{
  T ret = data.front();
  for(int i = 1; i < data.size(); i++)
  {
    if(data[i] < ret)
      ret = data[i];
  }
  return ret;
}

int main(void)
{
  const std::vector<int> data{64, 89, 21, 64, 98, 03, 26, 90, 48, 30, 92, 14, 98, 32, 17};
  std::cout << min(std::span{data}) << std::endl;
  return 0;
}

When should you use it?

There’s a nice stackoverfow post that talks about when not to use a std::span. One of those cases is in cases where begin and end iterators would be better. You could definitely argue in my above example it would be better off using begin and end iterators.

That same stackoverflow post also mentions many reasons why std::span is awesome. I strongly recommend you check it out.

I’ll be honest I’m personally looking for more cases of when to use std::span instead of begin/end iterators; however I’ll definitely say that std::span seems to be much better than std::vector &


In conclusion I hope this gets you curious about std::span. With the advent of C++20 std::span will be come much more common in C++ code and I’m definitely excited about that.

Thanks for your time, Tyler Sean Rau

Written on September 25, 2023