Author Topic: Span - C++20  (Read 3368 times)

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Span - C++20
« on: February 25, 2019, 04:41:49 AM »
I came across some discussion of span, which may find its way into the C++20 standard.

The span proposal is for a non-owning view into contiguous memory, such as is held by a std::vector, std::array, or built in array. It is conceptually similar to, and may be implemented with, a pointer and a length pair. It does not allocate or free the memory it accesses, and so does not risk allocation related exceptions. It does however require the memory it is pointed at to outlive the view's lifetime.

One particular use for a span is as a function parameter. This would allow a function to accept any contiguous container as an argument. For example, any of std::vector, std::array, or built in arrays could be passed as arguments, which would be converted to a span at the call site.

This is similar to string_view, which is able to handle both null-terminated C-style string literals, and the C++ style std::string. It is also a non-owning view of the string, and is also conceptually similar to a pointer and length pair.

You might think of span as something like a generalized type version of string_view. Though the exact details may get a little messier than that. In particular, string_view is meant as a read-only view into the string. As such the iterator member type is defined to be equal to the const_iterator member type, and internally it contains a const CharT*. In contrast, the span type is meant to be usable in a mutable context. This has implications concerning Regularity, which impacts copy, assignment, and comparison operators, and is related to treating user defined types as value types.

There's a paper on the design of span, which is interesting, though skip the change log. There's also a discussion Should Span be Regular? which has some interesting discussion on value type semantics, and how this impacts some of the operators.


Edit: Correct link to span documentation.
« Last Edit: February 25, 2019, 07:05:42 AM by Hooman »

Offline leeor_net

  • Administrator
  • Hero Member
  • *****
  • Posts: 2352
  • OPHD Lead Developer
    • LairWorks Entertainment
Re: Span - C++20
« Reply #1 on: February 25, 2019, 07:01:20 AM »
This seems like a way to reduce templating, perhaps? If I needed a function to be generalized in terms of containers, I would just templatize it and require that it use STL conventions. But I also don't deal too much with super generalized all-purpose functions like that, only now and then.

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Span - C++20
« Reply #2 on: February 25, 2019, 08:52:49 AM »
Correct. Using a span means a single function instance that can handle each of the container types.

Of course span itself is a template, but much like with std::vector and std::array, parameters would be a specific instance of one, making it a fixed type from the perspective of the function.

Note that I said a single function instance above, not simple a single function in terms of source code. As each of the container types can construct a span object referencing their contents at the point of call, they all call the exact same generated code, even for different container types. This would be a way of combating code bloat due to template instantiations.

Offline leeor_net

  • Administrator
  • Hero Member
  • *****
  • Posts: 2352
  • OPHD Lead Developer
    • LairWorks Entertainment
Re: Span - C++20
« Reply #3 on: February 25, 2019, 06:07:04 PM »
That was going to be my next question -- a true advantage over templating would be to eliminate the bloat that comes with it. This sounds like it addresses that.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Span - C++20
« Reply #4 on: February 25, 2019, 07:48:59 PM »
In C#, you can just use the Interface IEnumerable<T> when passing a container into many library functions. This is nice because it can take a list, array, linked list, custom container that defines IEnumerable, etc by default. It sounds like range will bring that ease to C++, which will be a boon. Especially when trying to write more generic library code.

Of course if it is implemented in 2020, it will probably be another 3 years before all the major compilers implement it, just like the std::filesystem still seems to be in limbo from C++17. :|

-Brett