Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is std::span a pointer + size and not two iterators

It appears that std::span in C++20 is defined similarly to

template<class T>
class span
     {
     T* begin;
     size_t count;
     };

And not

template<class Iter>
class span
     {
     Iter begin;
     Iter end;
     };

which is more general (works with std::list, std::map, etc)?

like image 830
user877329 Avatar asked Jun 28 '19 18:06

user877329


1 Answers

The whole point of std::span<T> is to be a view over contiguous data. pair<T*, size_> (or something like it) is the right way to represent that view. You cannot have a std::span that is a view over a std::list or a std::map, so it doesn't make sense to come up with a way to represent it. The point is to be a common, vocabulary type to just accept contiguous data.

It's also very important span is effectively type-erased. A span<int> could refer into a int[20] or a vector<int> or a int[] that is dynamically allocated somewhere or a llvm::SmallVector<int> or a ... It doesn't matter where it comes from, you just have the one type that is: "view over some contiguous ints".

It is true that pair<Iter, Iter> (or, more generally, pair<Iter, Sentinel>) is a more general representation that would work for more containers. There is such a thing in C++20 as well, it's called std::ranges::subrange<I, S>. But note here that we don't have the type-erasure aspect... a subrange over a map<K, V> will have a different type than a subrange over a different container with the same value_type, like list<pair<K const, V>> or vector<pair<K const, V>> or multimap<K, V>.

like image 69
Barry Avatar answered Sep 29 '22 11:09

Barry