为什么string_view而不是generalized container_view <T>?

Loo*_*pes 15 c++ string string-view c++17

我发现新C++ 17标准的string_view有点多余.

我们有一个非常详细的简单机制集合,用于将数据传递给被调用者,没有太多开销,现在又有一个也只针对一种容器类型.

我不明白为什么只为字符串提供这种机器而不是为其他容器提供更普遍的类型.一个明智的答案是我们已经有了这些解决方案.例如,在C++ 17及更高版本中,演示文稿string_view被解释为observer_ptr<T> (or T*) for string.

与C++ 17引入的string_view相比,请说明针对更通用的container_view的参数.

Nic*_*las 14

广义container_view更恰当地称为范围.我们有一个完全专注于范围概念的TS航路.

现在,我们有string_view一个单独的类型,因为它有一个专门的字符串特定的接口来匹配特定于basic_string字符串的接口.或者至少,匹配const/non-allocation接口.

请注意,container_view或者您调用的任何内容都将无法删除与生成它的容器的连接.或者至少,不是没有在每次访问/操作上支付类型擦除开销.

相比之下,string_view基于const char*s和整数.那个班并不关心字符串的来源; 它提供了一个连续的角色数组的视图,无论谁拥有它.它可以这样做,因为它知道源是一个连续的数组,因此使用指针作为其迭代器的核心.

你不能为任意容器做到这一点.你container_view<vector>会有不同的迭代器container_view<list>.它必须.这意味着如果您将a container_view作为函数参数,则必须选择要使用的特定容器(强制用户提供该容器类型),使您的函数成为模板,或者使用类型擦除的迭代器范围(因此速度较慢) ).

也有后C++ 17级的GSL类型的建议spanmdspan.前者表示连续数组的可修改"视图" .后者表示您视为多维的连续数组的可修改"视图".


Ven*_*Ven 5

string_view提供的不仅仅是一个简单的字符串指针。您需要将其视为不仅仅是一个简单的非拥有指针:如果这就是全部,则string_view不能允许您“切片”字符串的一部分,并对它应用操作(同时仍然是一个视图;因此不是产生复制费用):

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
Run Code Online (Sandbox Code Playgroud)