[Development] QList
Marc Mutz
marc.mutz at kdab.com
Sat Mar 18 18:37:15 CET 2017
Ville,
A word of warning: when it comes to QList, there's a very vocal minority that
claims that either QList works perfectly well or else ain't so bad. But
afaict, there's consensus between the people who actually count (sorry to be
blunt, but Qt is not a democracy, but a meritocracy) that QList as-is
currently was a mistake and needs to go in Qt 6. The only difference in
opinion is how to cushion the fall.
Lars, Thiago: it would be nice if you could confirm (or deny, in case I
misinterpreted) the above as soon as you can. Otherwise this thread will
derail massively again.
On Saturday 18 March 2017 11:25:12 Ville Voutilainen wrote:
[...]
> > Kill QList in Qt 6.
>
> How much valid code will that break? How many bugs does that avoid?
Tons. Qt uses QList as the default container since Qt 4.0. Before, it used
QValueList, a doubly-linked list. Qt has a very bad track record for its
default container choice.
We do need to think very carefully about an exit strategy, indeed. What I
wrote in the mail you quote from was the part that deals with not introducing
new uses of QList. We need also deal with existing use, even though we can
hope for clang-based refactoring tools to do the bulk of the work.
But we simply cannot, in 2020, continue to use a
std::vector<std::unqiue_ptr<T>> as our default container. That's simply
ridiculous.
> > This experience, over several years, has thaught me that we need a
> > technical solution. And so we started to specialize QList<QNewType> as
> > an empty class. So far, this is the only workable solution I have found,
> > and believe me, I am very determined.
>
> As a technical point, reminding me of how std::hash is 'poisoned', and
> why std::experimental::fundamentals_v2::nonesuch
> exists, you might want to also prevent default construction, copy/move
> construction and copy/move assignment.
> Otherwise an innocent user might create an object of such a type, pass
> it into a generic function and
> get a fairly unwelcoming error deep in an instantiation chain.
Keep that in mind. You'll almost certainly be reviewing any such changes.
> > So, here's my proposal for a QList exit strategy:
> >
> > In Qt 5:
> >
> > 1. Replace QList in generic code by QListOrVector, tell users to hold
> > QLists
> >
> > they get from Qt API only in type-deduced variables.
>
> In other words, introduce generic code where there wasn't generic code
> before - users writing
> non-generic code calling non-templates that return QLists will need to
> use deduction or a metaprogramming tool.
No, that is false. You can keep using QList for now everywhere you used it so
far, in non-generic code. Nothing changes for existing types. And for new
types, the compiler will make sure that you don't get away with QList. We do
recommened to use auto to receive QLists to avoid having to port these code
lines manually come Qt 6. I do not consider auto variables "generic code".
> > 2. Fix any QList API missing (and not actively harmful) on QVector. E.g.
> > I
> >
> > don't think toSet() should be either on QList nor QVector, because it
> > creates nonsense like qHash(QItemSelectionRange) (please, please, look
> > it up :)
> >
> > 3. Disable QList for all new QFoo value types (by specializing
> > QList<QFoo> as
> >
> > an empty class).
> >
> > 4. Provide QArrayList for code that needs stability of references
> > (stability
> >
> > statically checked in Qt 5, enforced in Qt 6).
>
> It seems that (4) is perfectly safe, whereas (2) and (3) are breaking
> changes; to what extent, I would like to know.
(2) is possibly breaking, yes. We should intercept by deprecating
QList::toSet() and re-adding it as a free function.
(3) is breaking nothing for existing code, since it only applies to new types.
New types don't magically show up in your source code. You have to introduce
them yourself. As for existing generic code, it's a source-incompatibility
that is accepted, because it can be fixed by using auto variables. Or you
don't use the new type at all. I mean, we're not talking about QString here.
With very few exceptions, any type we're adding now will not get widespread
use before Qt 6, anyway. One exception hopefully being QStringView.
> > In Qt 6:
> >
> > 5. Replace all QList uses left with ... what ? QVector? std::vector?
> >
> > -> separate discussion
> >
> > 6. Kill QList or keep it as a deprecated class.
>
> This certainly seems feasible, but the migration and the extent of it
> its interesting. There's a fair bunch
> of QList-using code out there, afaik.
Indeed, if it was easy, it would have been done long ago. But it's nonetheless
absolutely necessary. Q6String will not fit into a QList anymore. QVariant and
QModelIndex already don't. And given the extensive use of QVariant in QML/Qt's
property system, I don't think anyone can be happy about the per-element
memory allocation in QVariantList.
Thanks,
Marc
--
Marc Mutz <marc.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt, C++ and OpenGL Experts
More information about the Development
mailing list