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.