什么是string_view?

问题描述 投票:0回答:2

string_view
是添加到 C++17 的 C++ 库基础 TS (N3921) 中提议的功能

据我了解,它是一种代表某种字符串“概念”的类型,它是可以存储可作为字符串查看的内容的任何类型容器的视图。

  • 这是对的吗?
  • 应该规范
    const std::string&
    参数类型变为
    string_view
  • 还有关于
    string_view
    需要考虑的另一个重要点吗?
c++ c++17 string-view fundamentals-ts
2个回答
250
投票

任何和所有类型的“字符串引用”和“数组引用”提案的目的都是为了避免复制已经在其他地方拥有并且只需要非变异视图的数据。所讨论的

string_view
就是这样的一项提案;还有早期的也称为
string_ref
array_ref

这个想法始终是存储一对指向第一个元素的指针和一些现有数据数组或字符串的大小。

这样的视图句柄类可以通过值廉价地传递,并提供廉价的子字符串操作(可以通过简单的指针增量和大小调整来实现)。

字符串的许多用途不需要实际拥有字符串,并且相关字符串通常已经由其他人拥有。因此,通过避免不需要的副本,确实有提高效率的潜力(想想您可以节省的所有分配和异常)。

原始的 C 字符串存在这样的问题:空终止符是字符串 API 的一部分,因此您无法在不改变底层字符串的情况下轻松创建子字符串(

strtok
)。在 C++ 中,通过单独存储长度并将指针和大小包装到一个类中,可以轻松解决此问题。

我能想到的一个主要障碍和与 C++ 标准库哲学的分歧是,此类“引用视图”类与标准库的其余部分具有完全不同的所有权语义。基本上,标准库中的其他所有内容都是无条件安全和正确的(如果可以编译,那就是正确的)。有了这样的参考类,情况就不再是这样了。程序的正确性取决于使用这些类的环境代码。所以检查和教学都比较困难。

注意if C++17 的

std::string_view
是从/为
std::string
创建的,那么一旦所述
std::string
超出范围,所述
std::string_view
的行为将是未定义的.
另外,
Qt
框架将
QStringRef
重命名为
QStringView
but都表示Qt类增加了查看/引用的
QString
的引用计数,因此Qt没有超出范围的问题(至少没有)对于
QStringRef or 
QStringView`)。


7
投票

(2021年自我教育)

来自微软的

模板专业化的 string_view 系列提供了一种有效的方法,将只读、异常安全、非拥有的句柄传递给任何类字符串对象的字符数据,其中序列的第一个元素位于位置 0。 (...)

来自 Microsoft 的 C++ 团队博客 std::string_view: The Duct Tape of String Types 2018 年 8 月 21 日(2021 年 4 月 1 日检索):

string_view 解决了参数的“每个平台和库都有自己的字符串类型”问题。它可以绑定到任何字符序列,因此您可以将函数编写为接受字符串视图:

void f(wstring_view); // string_view that uses wchar_t's

调用它时无需关心调用代码使用的是什么字符串类型(并且 > for (char*, length) 参数对只需在它们周围添加 {} ) (...)

(...)

如今,用于传递字符串数据的最常见的“最低公分母”是空终止字符串(或标准称其为空终止字符类型序列)。这早在 C++ 出现之前就已经存在,并提供了干净的“扁平 C”互操作性。然而,char* 及其支持库与可利用代码相关联,因为长度信息是数据的带内属性并且容易被篡改。此外,用于分隔长度的 null 禁止嵌入 null 并导致最常见的字符串操作之一(要求长度)与字符串的长度呈线性关系。

(...)

每个编程领域都构成了自己的新字符串类型、生命周期语义和接口,但许多文本处理代码并不关心这些。仅仅为了使不同的字符串类型满意而分配整个数据副本进行处理对于性能和可靠性而言并不是最佳选择。

© www.soinside.com 2019 - 2024. All rights reserved.