15

I've found string_view from new C++17 standard a bit redundant.

We've got a quite verbose collection of simple mechanisms for passing data to callee, without much overhead and now there is one another which is also specific only to one container type.

I don't understand why providing this machinery only for string and not some more generalized type for other containers. One sensible answer is that we've already had these kinds of solutions. For example in C++17 and beyond presentation string_view is explained as observer_ptr<T> (or T*) for string.

Please state the arguments against a more general container_view, in contrast to the string_view introduced by C++17.

Community
  • 1
  • 1
LookAheadAtYourTypes
  • 1,451
  • 2
  • 20
  • 31
  • 4
    I think the `observer_ptr` comparison just creates confusion and detracts from the question of whether there should be a generalized `container_view` instead of the specific `string_view`. – juanchopanza Aug 19 '16 at 08:37
  • 2
    Because operations on strings are the most common programming task? I think the answer is straightforward. – Jesse Good Aug 19 '16 at 08:40
  • container_view would not work on a single `const char*`, but `string_view` has the additional assumption that such a pointer points to a *string*, being terminated with a `\0` when it is constructed with that single-pointer constructor. – Johannes Schaub - litb Aug 20 '16 at 11:01

2 Answers2

14

A generalized container_view is more properly called a range. We have a TS en-route devoted entirely to range concepts.

Now, we have string_view as a separate type because it has a specialized, string-specific interface to match basic_string's string-specific interface. Or at least, to match the const/non-allocating interfaces.

Note that container_view or whatever you called it would be incapable of erasing its connection to the container that generated it. Or at least, not without paying type-erasure overhead on each access/operation.

By contrast, string_view is based on const char*s and integers. That class doesn't care where the string came from; it provides a view into a contiguous array of characters no matter who owns it. It can do this because it knows that the source is a contiguous array, and therefore uses pointers as the core of its iterator.

You can't do that for arbitrary containers. Your container_view<vector> would have different iterators from container_view<list> or whatever. It would have to. Which means if you take a container_view as a function parameter, you must either pick a specific container to use (forcing the user to provide exactly that container type), make your function a template, or use a type-erased iterator range (thus being slower).

There are also post-C++17 proposals for the GSL types span and mdspan. The former represents a modifiable "view" of a contiguous array. The latter represents a modifiable "view" of a contiguous array that you treat as multi-dimensional.

Nicol Bolas
  • 378,677
  • 53
  • 635
  • 829
4

string_view offers more than a simple pointer on string. You need to look at it as more than a simple non-owning pointer: if that's all it were, string_view couldn't allow you to "slice" parts of the string, and apply operations to it (while still being a view; thus not incurring the cost of copy):

char *s = "welcome to stackoverflow";
auto s = std::string_view{s + 8, 2}; // a view on "to"
// you can then apply many operations on this view, that wouldn't make sense more on your general non_owning<T>:
s.remove_prefix(std::min(s.find_first_not_of(" "), s.size()));
// it also "inherits" (copies the API) a lot directly from std::basic_string
auto view2 = s.substr(3, 4); // a generic non-owning ptr would copy here, instead of giving you a new view
Ven
  • 18,663
  • 2
  • 38
  • 58
  • Is there something that keeps us from providing the same behaviour of "view" for other containers? – LookAheadAtYourTypes Aug 19 '16 at 08:53
  • 1
    Not really. That's why Boost, for example, has `array_view` (and boost.fusion another type of views for filter, map, etc). The only issue is that you need to do it manually, because as I demonstrated here, you need specific behavior for each container. – Ven Aug 19 '16 at 08:55
  • 1
    @tomekpe Also there are several competing proposals to include a generic range view into the standard (and even a mutable range view called a « span » as the one provided in Microsoft GSL). The proposals might need to reach design agreement before vendors start implementing it. – Morwenn Aug 19 '16 at 13:21
  • 1
    There should be two different `s`es, I sure. – Tomilov Anatoliy Aug 19 '16 at 14:55