[Development] RFC: Proposal for a semi-radical change in Qt APIs taking strings

Thiago Macieira thiago.macieira at intel.com
Tue Oct 13 23:01:38 CEST 2015


On Tuesday 13 October 2015 22:46:36 Marc Mutz wrote:
> Q: What mistakes do you refer to?
> 
> A: The fact that it has copy ctor and assignment operator, so it's not a
> trivally-copyable type and thus cannot efficiently passed by-value. It may
> also be too large for pass-by-value due to the rather useless QString
> pointer (should have been QStringData*, if any). Neither can be fixed
> before Qt 6.

Not even in Qt 6. The reason why it uses a QString pointer is that it follows 
the QString through reallocations. If the QString is mutated, the QStringRef 
will still be valid (provided it isn't shortened beyond the substring the 
QStringRef points to). There's a lot of code that depends on this, so we can't 
change it.

> Q: Why size_t?
> 
> A: The intent of QStringView (and std::experimental::string_view) is to act
> as an interface between modules written with different compilers and
> different flags. A std::string will never be compatible between compilers
> or even just different flags, but a simple struct {char*, size_t} will
> always be, by way of it's C compatibility.
> 
> So the goal is not just to accept QString, QStringRef, and (QChar*,int) (and
> QVarLengthArray<QChar>!) as input to QStringView, but also
> std::basic_string<char16_t> and std::vector<char16_t>.

The C++ committee's current stance on signed vs unsigned is that you should 
use signed for everything, except when you want to have modulo-2 overflows. 
We're not overflowing, so it should be signed.

> Q: What future do you have in mind for QStringRef?
> 
> A: None in particular, though I have found a need for an owning QStringRef
> in some places. But I expect Qt 6' QString to be able to provide a
> restricted view on shared data, such that it would subsume QStringRef
> completely.

We should deprecate it if QStringView comes into being.

> Q: What about QLatin1String?
> 
> A: Once QString is backed by UTF-8, latin-1 ceases to be a special charset.
> We might want something like QUsAsciiString, but it would just be a UTF-8
> string, so it could be packed into QStringView.

Since QString will not be backed by UTF-8, the answer is irrelevant.

> Q: What about QByteArray, QVector?
> 
> A: I'm unsure about QByteArrayView. It might not pull its weight compared to
> std::(experimental::)string_view, but I also note that we're currently
> missing a QByteArrayRef, so a QBAView might make sense while we wait for
> the std one to become available to us.

Given the mistakes that you and I are pointing out in QStringRef, we should 
not add QByteArrayRef. Instead, it should be in the new-style, in which case I 
wonder whether we should add a class in the first place. And moreover, how 
often is this needed? std::array_view should be plenty for QByteArray and 
QVector where needed.

> I'm actively opposed to a QArrayView, because I don't think it provides us
> with anything std::(experimental::)array_view doesn't already.

Right.

> Q: What do you mean when you say "abandon QString"?
> 
> A: I mean that functions should not take QStrings as arguments, but
> QStringViews. Then users can transparently pass QString, QStringRef and any
> of a number of other "string" types without overloading the function on
> each of them.
> 
> I do not mean to abandon QString, the class. Only QString, the interface
> type.

I'm not agreeing to the proposal just yet.

But as a condition to be even considered, it needs to be only for the methods 
that do not hold a copy of the string. That is, methods that immediately 
consume the string and no longer need to reference its contents.

Methods that keep a copy for any reason (e.g., QFile::setFilename) should 
still keep a QString API so that they can participate in the reference 
counting.

> Q: What API should QStringView have?
> 
> A: Since it's mainly an interface type, it should have implicit conversions
> from all kinds of "string" types, but explicit conversion _to_ those string
> types. It should carry all the API from QString that can be implemented on
> just a (QChar*, size_t) (e.g. trimmed(), left(), mid(), section(), split(),
> but not append(), replace() (except maybe the (QChar,QChar) overload.
> Corresponding QString/Ref API could (eventually) just forward to the
> QStringView one.

That makes sense.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center




More information about the Development mailing list