Why string_view instead of generalized container_view<T>?

别说谁变了你拦得住时间么 提交于 2019-12-01 02:36:32

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.

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!