如何在 Qt 小部件中使用 QStringView(或 QStringRef)?

How to use QStringView (or QStringRef) in Qt widgets?

我正在尝试用较轻的替代品 (QStringRef/QStringView) 替换较重的 QString class。问题是 Qt 小部件无论如何都不会使用这些 classes。比如QLabel::setText方法需要const QString&作为入参,让我的改进毫无用处。

我对这种差异感到困惑。那是故意的吗?有什么理由吗?如果在一天结束时没有人消费它们,QStringView 的用例应该是什么?

Qt 对自己的容器使用 CoW(写时复制)原则。这是一种有点过时的技术,但对于像 Qt 这样的大多数单线程 UI 框架来说工作正常。

官方文档在这里详细阐述了这一点: https://doc.qt.io/qt-5/implicit-sharing.html

正如 @m7913d 在评论和他的回答中指出的那样,大多数小部件确实在内部创建了一个本地副本,这就是 CoW 原则使事情变得快速的时候。

无论如何,我们在这里处理 UI,大量绘图,OS API,抽象层,巨大的(与字符串大小相比)帧缓冲区等等。可能他们稍后会在他们的 API 中添加 StringViews 并更改他们的体系结构,为 QStrings 添加 SSO,但显然这现在不是紧急情况。

Qt 曾经像 10-15 年前一样进步。 CoW、Qt 容器、大量日常用品库、可用性。但是现在所有这些东西都落后于现代 C++ 和 STL,Qt 鼓励他们的用户依赖 STL 容器并且仅将 Qt 类似物用于 API.

的操作。

没有人想要并行的 STL 和每个库的 Qt 版本。

至于 QStringView,我认为它的目的是为用户 类 提供一种与 QString 交互的现代视图机制。例如,您使用 QXML 从 xml 个文件中提取大量数据。然后你必须以某种方式分析这些数据——你不需要与 API 交互,但你已经有了 QStrings。为了使事情更新并更快一些 - 这里是 - QStringView。

QStringQStringRefQStringView 有不同的用例:

  • QString: the default class to store a string in Qt. It uses implicit sharing to avoid unneeded (read only) copies. Note that you may construct it efficiently by using f.ex. QStringLiteral 对于静态字符串:

    [...] For most purposes, QString is the class you want to use. It is used throughout the Qt API [...]

  • QStringView:当您不想存储字符串(并关心构造 QString 的开销)时,作为函数参数很有用:

    QStringView is designed as an interface type; its main use-case is as a function parameter type. When QStringViews are used as automatic variables or data members, care must be taken to ensure that the referenced string data (for example, owned by a QString) outlives the QStringView on all code paths, lest the string view ends up referencing deleted data.

    If you want to give your users maximum freedom in what strings they can pass to your function, accompany the QStringView overload with overloads for [...] QString if you store an unmodified copy of the string and thus would like to take advantage of QString's implicit sharing.

    QLabel 绝对应该存储 text 字符串(在绘制事件期间绘制它或实现 getter 函数)。因此,提供 QStringView 重载不会是一种改进。

  • QStringRef:对低级字符串解析很有用:

    This class is designed to improve the performance of substring handling when manipulating substrings obtained from existing QString instances. QStringRef avoids the memory allocation and reference counting overhead of a standard QString by simply referencing a part of the original string. This can prove to be advantageous in low level code, such as that used in a parser, at the expense of potentially more complex code.

请注意,只有 QString 拥有字符串的所有权,对于其他两个,应由程序员确保引用的字符串仍然存在。

结论QStringQLabel::setText.

的界面中使用是正确的class

进一步阅读