
Andrey Semashev wrote:
And fixed extents are not as useful as the dynamic extent in general, in my experience, as most of the time we deal with variable-sized sequences.
I also used to think that way, but that was because I didn't understand the purpose of span. The purpose of span is to replace pointer arguments. If your function takes void f1( unsigned char p[] ); you use void f1( span<unsigned char> p ); and if it takes void f2( unsigned char p[4] ); you use void f2( span<unsigned char, 4> p ); The fixed extent span here does two things: first, it inserts a runtime check that the extent of the passed span is >= 4. void g( span<unsigned char> p ) { f2( p ); // implicit assert( p.size() >= 4 ); } Second, it can be used to optimize out runtime checks in operator[]: void f2( span<unsigned char, 4> p ) { uint32_t v = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24); } Since it's statically known that 0<4, 1<4, 2<4, 3<4, these accesses don't cause any asserts to be inserted.