Why string_view instead of generalized container_view<T>?

怎甘沉沦 提交于 2019-12-09 02:27:53

问题


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.


回答1:


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.




回答2:


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


来源:https://stackoverflow.com/questions/39034413/why-string-view-instead-of-generalized-container-viewt

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