Howdy,

Il 03/03/21 16:53, Andrei Golubev ha scritto:
Hello,

I've been now working for a while with literals that have to (eventually) be converted to QString one way or another. While in certain cases (e.g. myMsg == u"This is my message" or u"Hello, " + world) character literals are handled neatly by some underlying machinery, pure assignments just don't work well:

QString hello = u"Hello"; // oops, compilation error

There's an explicit ctor that accepts QChar*, but if you end up with it, QString would allocate a memory to store whatever QChar* points to. Same is true for QString::fromUtf16().

Assuming that you do want the allocation (as QString constructors all allocate), the reason why a QString(char16_t*) constructor does not exist, IIRC, is to keep our API upgradable from QString to QStringView. Say you have a function taking QString today, and tomorrow you realize it could do with QStringView, it would constitute a very annoying source break if you just called it with f(u"text") (call becomes ambiguous).

But you can also decide to call this plan off and add the relevant constructor.

There's QStringView (and friends) which may aid you, but what if there's a list of strings that is populated? QList<QStringView> is not really an option if half of the strings are not literals. Then the next choice is QStringList in which case you need to do QStringView::toString() - well, bad luck, you end up allocating memory again.

There's of course QStringLiteral:
QString hello = QStringLiteral("Hello"); // yay, it works
... and, actually, QStringLiteral in Qt 6 is great, because it doesn't allocate the memory* to store that literal.

Wasn't it the same in Qt 5 as well?


But writing "QStringLiteral" each time is a bit inconvenient: let's be honest, it's a lot of code to type. You may want to write it once or twice, but how about a fifty or a hundred times?

* unless you modify the resulting string, of course

---
Here's my proposal: let's introduce a user-defined literal [1] for QString (and I volunteer to do it).

At least in Qt 5 this was really complicated and subject to compiler limitations. With the new implementation of QString in Qt 6 I guess this should be relatively easy to do?


How this would look for a user: instead of typing *QStringLiteral*("Hello") you would have something like *u*"Hello"*_q*. And the new code of course behaves exactly like the QStringLiteral()

This is actually a very open question: should it behave like QStringLiteral (not allocate, payload in .rodata, etc.) or like QString's constructor (allocate)? For instance, if you know you're going to allocate immediately afterwards (say, you're using .arg()), then does the QStringLiteral strategy still make sense here?


Well, to be good citizens, we probably need to scope the user-defined literal (e.g. similarly to std::chrono_literals [2]). Given that, how you would really write your code is similar to:

using namespace <whatever>; // done only once in a .cpp file
u"Hello"_q; // "u" in front and suffix "_q" are written every time

This is the proposal in a nutshell. I'd like to have some feedback and then some suggestions regarding:

  * Whether we want this for QByteArray as well (similarly to QString it
    allows "from raw data" construction, but then it's not really a
    string class, is it?)

I don't see the difference; we have QByteArrayLiteral, so a UDL for it also makes sense.


  * What suffix to use: in the example above I used "_q", but maybe
    "_qs" is better or something totally different

I'd go for _qs.


  * How to call a namespace: I'd probably go with "QtLiterals" but
    (looking at [2]) maybe there should be a richer hierarchy? For
    example, "QtLiterals::StringLiterals", so that the suffix could be
    reused without conflicts, etc.

Exactly:

https://codereview.qt-project.org/c/qt/qtbase/+/191717/16/src/corelib/tools/qangle.h#562



  * Whether *View classes need it (in theory they should allow implicit
    construction, so probably not)

They don't need it. QStringViewLiteral was scrapped as soon as we could rely on MSVC doing the right thing for u"foo". String view should be implictly constructible from any contiguous range of char-like types.


Thanks,

--
Giuseppe D'Angelo | [email protected] | Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
KDAB - The Qt, C++ and OpenGL Experts

Attachment: smime.p7s
Description: Firma crittografica S/MIME

_______________________________________________
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development

Reply via email to