R
What's the advantage of using "span"?Mostly, a little more security (mainly when combined with static analysis) and sometimes convenience.A brief definition span<T>:It is an abstraction that provides a view about a type data sequence T somewhere in memory. Note that the term ”view” is important, since it indicates the fact that one span span only “look” to objects, but is not their owner or even manages them. It is quite simple and almost no cost.One span span is not sequence in itself, but a structure that contains a pointer to value T initial and the length of this sequence, that is, { T *ptr; std::size_t length; }.See then that basically one span span is a simple abstraction that knows an initial point of memory and a length, which defines its limits.This “length” is essential for ensuring that, using a span span, you will not access objects beyond your reach. This makes the program more reliable and safe.One span<T> can be static or dynamic. Static in the sense that its length is known by the compiler – in cases like this the span span you don't even have to have the field length (it is even cheaper!). In such cases, there are also a number of guarantees that can be made statistically, so that access a value outside the limits of the span span is a clear error that prevents the build of the program.Of course the same security guarantees when trying to access values outside the limit also apply to spans dynamic, but in this case the checks are obviously made in runtime.This kind of guarantee undoubtedly leads to higher quality programs. Compare one span<T> with the famigerado par (T*, length) – in the last case nothing prevents the programmer from accessing a value that exceeds the limits stipulated by length.In addition, one can not fail to elect a certain gain greater possibilities of modularization, composition and code reuse. This is evident in the very code of the question.See that one span<T> can be trivially built from C-style arrays, std::arrays std::vectors and other containers. Like span span does not represent mechanism data storage and management, but only one Preview about them, it is very easy to use it to represent the sequence of data from various containers (like the std::array or std::vector).Why should I prefer to use span<T> in place of a pointer?Not the pointer. They're different things.But the pointer language and length is encouraged “insecure” compared to span<T>. There is no guarantee that the length passed by the pointer in fact will be used as limit. O span span ensures that this invariant is fulfilled.In new code it is indicated to use a span span instead of the pointer-length pair to represent a continuous sequence of objects.Why should I prefer to use span<T> in place of a reference for container?Because it is more generic and cheaper, but it is generally important to understand the differences.O span span provides access to the elements of the sequence to which it visualizes. Also allows modification of these elements (assuming it is a span<T> and not one span<const T>, for example).However, span span does not allow to modify the sequence size to which it sees. Adding a new element to the sequence, for example, cannot be done with span span. In this kind of situation, obviously, it is not possible to receive a span span, but rather a reference to the container that allows modification of its size, as itself std::vector. You're on a case-by-case basis.Generally speaking, when you only want to move data from a specific sequence (including generically between various types of containers), span span can be quite useful.Why should I prefer to use span<T> in place of an iterator?One span span is not conceptually the same as an iterator. An iterator is an abstraction for iterate about values. One span span is abstraction about viewing a continuous sequence of data. There is, however, the possibility of creating an iterator from a span span. Reciprocal is not necessarily true.Some important observations to be made:It is crucial to emphasize the fact that the span span He doesn't own anything. It only provides a view to data belonging to another object (such as one std::array). The elements within the limits stipulated, however, are accessible by span span that, for example, does overload the operator[] for the access of the elements.span<T> was designed to be cheap to be built, copied, moved and used. Users are encouraged to use it with semantics of value.All data access within the limits of span span are conceptually range-checked to ensure that they continue within span bounds. Therefore, as long as a sequence is accessed by a span span correctly initialized, it is guaranteed that your limits cannot be violated.
In this sense, in reference implementations, for example, by violating a range-check, its name terminate(), but the implementation can choose to continue running with undefined behavior. In this case, obviously, it is considered fatal the ability of the program to continue a reliable execution.O span span is expected to be used in situations where previously used the pointer-length pair. It is a “safe substitute” for this type of language. It is, in this sense, extremely encouraged.To simplify the pass by parameters, span<T> provides several container builders commonly used to store continuous sequences of elements (such as std::array, std::vector, etc.). This was demonstrated in one of the code excerpts of the question itself. O span span is quite generic in this sense.I would not have been able to write this answer without these publications. I strongly based on: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0122r7.pdf https://stackoverflow.com/q/45723819/7445826