I occasionally tune into "C++ Weekly" on Youtube, and this is today's video: https://www.youtube.com/watch?v=zCzD9uSDI8c"C++ Weekly - Ep 361 - Is A Better `main` Possible?"
1) I mostly code in C++11 or earlier, so can someone who prefers span over vector please explain why it is your preferred container and/or when is it the better option?
2) I don't generally use smart pointers, but from my reading I got that a span will not keep a smart pointer alive, so how do you deal with that? Or is that the behavior that you are looking for?
1) A span isn't a replacement for a vector in general. A vector stores the data it contains. A span does NOT, it is just a pointer surrogate or a reference to data that you already stored elsewhere. So if the choice is making an extra copy of data into a new vector or using a span, you use the span, to avoid the copy. If the choice is what container to use, span is NOT a container...
2) situational. I am struggling to find a reason to use a span on a pointer in the first place, but if you did, which behavior you want is part of your design. You can always stuff the span into your own class and add a smart pointer to the class and hold onto it there as a locked reference, for a very simple solution. I know thou shalt not and all that, but you could even inherit the span into your class for something so simple, and its extra member is just silent and hidden, and nothing much to be done beyond the wrapper. Or maybe nothing needs to be done, if the pointer is alive, and you span it and iterate it, the span ends, pointer still alive... nothing to worry about.
I haven't really started using C++20 yet so I don't know exactly when I will use std::span.
I think it's quite similar to std::string_view except that it allows you to modify the underlying data unless you explicitly mark the element type as const (e.g. std::span<const T>).
One use case seems to be as a function parameter. By using std::span I can pass std::vectors, std::arrays and even raw arrays.
I don't generally use smart pointers, but from my reading I got that a span will not keep a smart pointer alive, so how do you deal with that? Or is that the behavior that you are looking for?
std::span is more like a "raw" pointer (not a "smart" pointer). You use it to refer to something else that you "own" or that you know will stay alive for as long as you use it.
This means it's generally safe to use std::span as function parameter, the same way that it's generally safe to use references (and pointers) as function parameters.
If you create a vector (or array) as a local variable inside a function (or as a member of a class) then you could use std::span to refer to portions of that vector. As long as the std::spans don't outlive the function (or class object), and you make sure the vector is not reallocated while using the std::spans, then you should be fine.
There are interesting things going on there, especially that it can make semi-generic functions. I good amount of code that I can use span in, and it's certainly worth keeping an eye open for chances to use it.
Thank you for the very in-depth answers.
std::span is a viable option only for containers which store the elements in contiguous memory; a pair of iterators or a range has no such restriction and is generally more flexible.
std::span is essentially a vocabulary type. From the proposal:
Thank you JLBorges, I checked out the pdf you linked, and it really had a very good explanation of the whole intent for the span type. It backs up what everyone has said, but it also helped to line things out.
While I was on that site I also grabbed a copy of the C++23 "Working Draft", I wasn't aware of how to get it before. (Even the draft doesn't give an intent, something that says "This is why we need this", so that PDF was excellent.)
I'm certainly bookmarking the site.