简体   繁体   English

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

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

I'm trying to replace heavy QString class with the lighter alternatives ( QStringRef / QStringView ).我正在尝试用较轻的替代品( QStringRef / QStringView )替换重型QString class 。 The problem is that Qt widgets don't consume these classes by any mean.问题是 Qt 小部件无论如何都不会使用这些类。 For example, the QLabel::setText method requires const QString& as an input parameter, making my improvement useless.例如, QLabel::setText方法需要const QString&作为输入参数,使我的改进毫无用处。

I'm confused with this discrepancy.我对这种差异感到困惑。 Is that on purpose?这是故意的吗? Is there any reason for that?有什么理由吗? What should be the use case for QStringView if at the end of the day no one consumes them?如果在一天结束时没有人使用QStringView应该是什么用例?

QString , QStringRef and QStringView have different use cases: QStringQStringRefQStringView有不同的用例:

  • QString : the default class to store a string in Qt. QString :默认的 class 用于在 ZE8801102A40AD89DDCFDCAEBF008D25Z 中存储字符串。 It uses implicit sharing to avoid unneeded (read only) copies.它使用隐式共享来避免不需要的(只读)副本。 Note that you may construct it efficiently by using f.ex.请注意,您可以使用 f.ex 有效地构建它 QStringLiteral for static strings:用于 static 字符串的QStringLiteral

    [...] For most purposes, QString is the class you want to use. [...] 对于大多数用途, QString是您要使用的 class。 It is used throughout the Qt API [...]它在整个 Qt API [...]

  • QStringView : is useful as a function parameter when you do not want to store the string (and care about the overhead of constructing a QString ): QStringView :当您不想存储字符串(并关心构造QString的开销)时,它可用作 function 参数:

    QStringView is designed as an interface type; QStringView被设计为接口类型; its main use-case is as a function parameter type.它的主要用例是作为 function 参数类型。 When QStringView s 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.QStringView用作自动变量或数据成员时,必须注意确保引用的字符串数据(例如,由QString拥有)在所有代码路径上QStringView ,以免字符串视图最终引用已删除的数据。

    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.如果你想让你的用户在他们可以传递给你的QStringView的字符串方面给予最大的自由,如果你存储了一个未修改的字符串副本并因此想利用QString的隐式共享。

    QLabel should definitely store the text string (to paint it during the paint event or to implement the getter function). QLabel绝对应该存储text字符串(在绘制事件期间绘制它或实现 getter 函数)。 So, providing a QStringView overload wouldn't be an improvement.因此,提供QStringView重载不会是一种改进。

  • QStringRef : is useful for low-level string parsing: QStringRef :对于低级字符串解析很有用:

    This class is designed to improve the performance of substring handling when manipulating substrings obtained from existing QString instances.此 class 旨在提高 substring 处理从现有QString实例获得的子字符串时的性能。 QStringRef avoids the memory allocation and reference counting overhead of a standard QString by simply referencing a part of the original string. QStringRef通过简单地引用原始字符串的一部分来避免标准QString的 memory 分配和引用计数开销。 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.这可以证明在低级代码中是有利的,例如在解析器中使用的代码,但代价是可能更复杂的代码。

Note that only QString takes ownership of the string, for the other two, it is the programmer who should ensure the referenced string still exists.请注意,只有QString拥有字符串的所有权,对于其他两个,程序员应该确保引用的字符串仍然存在。

Conclusion : QString is the right class to use in the interface of QLabel::setText .结论QString是在QLabel::setText接口中使用的正确 class 。

Further reading进一步阅读

Qt uses CoW (Copy-on-Write) principle for its own containers. Qt 对自己的容器使用 CoW(Copy-on-Write)原则。 It is a bit outdated technique, but works ok for a mostly single thread UI framework like Qt.这是一个有点过时的技术,但对于像 Qt 这样的大多数单线程 UI 框架来说工作正常。

The official documentation eleborates more on that here: https://doc.qt.io/qt-5/implicit-sharing.html官方文档在这里详细阐述了这一点: https://doc.qt.io/qt-5/implicit-sharing.html

As @m7913d noted in the comments and in his answer, most widgets do create a local copy inside and that is when the CoW principle makes things fast.正如@m7913d 在评论和他的回答中指出的那样,大多数小部件确实在内部创建了一个本地副本,这就是 CoW 原则使事情变得快速的时候。

Anyway, we are dealing with UI here, lots of drawing, OS API, abstraction layers, giant (compared to string sizes) framebuffers and what not.无论如何,我们在这里处理 UI、大量绘图、操作系统 API、抽象层、巨型(与字符串大小相比)帧缓冲区等等。 May be they will add StringViews to their API later and change their architecture, add SSO for QStrings, but apperently this is not an emergency now.可能他们稍后会将 StringViews 添加到他们的 API 并更改他们的架构,为 QStrings 添加 SSO,但显然现在这不是紧急情况。

Qt used to be progressive like 10-15 years ago. Qt 曾经像 10-15 年前一样进步。 CoW, Qt containers, lots of libs for everyday things, usability. CoW、Qt 容器、大量日常用品库、可用性。 But now all this stuff is lagging behind modern C++ and STL and Qt encourages their users to rely on STL containers and use Qt analogs only for operations with API. But now all this stuff is lagging behind modern C++ and STL and Qt encourages their users to rely on STL containers and use Qt analogs only for operations with API.

No one wants a parallel STL and a Qt version of every lib ever.没有人想要每个库的并行 STL 和 Qt 版本。

As for QStringView I think its purpose is to provide a modern view mechanism for user classes which interact with QStrings.至于 QStringView,我认为它的目的是为与 QStrings 交互的用户类提供现代视图机制。 For example, you use QXML to extract lots of data from xml files.例如,您使用 QXML 从 xml 文件中提取大量数据。 And then you have to analyze this data somehow - you do not need to interact with API, but you already have QStrings.然后你必须以某种方式分析这些数据——你不需要与 API 交互,但你已经有了 QStrings。 To make things up to date and a bit faster - here you are - QStringView.为了使事情更新并更快一点 - 你在这里 - QStringView。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM