Skip to content

Knowledgebase Programming: Qt Strings

Lars Toenning edited this page Dec 11, 2023 · 2 revisions

Qt Strings Overview

The best way to know which code construct to use in a given situation is to understand the API of the facilities you use, and what they provide.

String producers

  • QString
    • QString is a class that owns a shared, dynamically-allocated UTF-16 string.
    • The sharing is detached (so the string data is copied) when any non-const operation is performed (copy-on-write). When constructing a QString from a string literal, the data is always copied.
  • QStringLiteral
    • QStringLiteral is a macro that "returns" a QString
    • The internal shared data of theQString is prepared at compile-time, not dynamically allocated, and not copied. If you have a string literal, and you need a QString, then QStringLiteral is what you want. But you don't always need a QString. In situations where you don't need a QString, it is a waste of time to use QStringLiteral.
  • QLatin1String
    • QLatin1String is a class that holds a const char* pointing to a string literal.
    • Its use cases are limited, as converting it to a QString involves converting the Latin-1 data into UTF-16. Certain Qt functions are overloaded for QLatin1String because they can directly use the Latin-1 data without converting it to UTF-16. For example, JSON keys can be passed as QLatin1String. In such cases, using a QString would perform an unnecessary allocation and convertion from Latin-1 to UTF-16 and back again.
  • QStringView
    • QStringView is a class that holds a const char16_t* pointing to some UTF-16 string.
    • It is often useful as a function parameter type. If you write a function that takes a string parameter, which it uses and then discards, it can be beneficial to declare the parameter as QStringView. The caller can then choose to pass a string to your function using whatever type is most convenient to them. If they had a char16_t* then they would not be forced to construct an unnecessary QString just to be able to pass it to your function.
    • If your function really does need a QString, don't use QStringView as it would inhibit the implicit sharing feature of QString. Because QStringView is such a simple class, it is more efficient to pass it by value, not reference.
  • QStringRef
    • QStringRef is a class that references a substring of an existing QString without copying it.
    • This can be useful when working with substrings, where you would otherwise be allocating unnecessary temporary QString instances to copy substrings into them. For example, s.leftRef(3).trimmed() instead of s.left(3).trimmed().
    • Of particular note is QString::splitRef, which is like split except that it returns a QVector<QStringRef> instead of a QStringList. Using QStringList would be very inefficient if you just want to loop over the parts, as it would reallocate and copy every single one for no reason.
    • Just make sure that the QStringRef gets destroyed //before// its referenced QString, otherwise this would be a dangling reference.
  • QChar
    • QChar is a class that contains a single UTF-16 character.
  • QLatin1Char
    • QLatin1Char is a class that contains a single Latin-1 character.

String consumers

  • QString::arg
    • arg is a member function of QString,
      • so obviously if you want to call arg then you need a QString to call it on. So if you want to call arg on a string literal, then you almost always want QStringLiteral. The same goes for other member functions of QString. But note that QStringView and QStringRef provide many of the same methods.
  • operator %
    • The % operator provides more efficient string concatenation when <QStringBuilder>is included.
    • Instead of using lots of temporary QString objects to store each subexpression (like + does) it collects the parts together and concatenates them all in one go.
    • You should look in the qstringbuilder.h header to see which types can be concatenated. The class template QConcatenable is specialised on each concatenable type: QString, QStringRef, QStringView char16_t*, etc. So for string literals, these can be concatenated directly as UTF-16 literals, without any QString-based intermediary
    • One rare exception to the above rule: if every type in a given concatenation is a fundamental type like char* or char16_t*, it will fail to compile. This is because operators can obviously not be overloaded on built-in types. At least one of the parts of the concatenation must be a class type. The best workaround is QStringView as it is the most lightweight.

TL;DR

It can take time and experience to cement the understanding in the brain so that it becomes intuitive (to become "fluent"). Therefore when working with string literals you can use the following cheat sheet that should cover most situations:

Empty string Single character Multiple characters
Store in a QString QString() QStringLiteral QStringLiteral
Concatenate with % u' ' u" "
As QLatin1String QLatin1String() QLatin1String QLatin1String
As QStringView parameter u"" u" " u" "
Clone this wiki locally