[Development] HEADS UP: Don't use QList, use Q_DECLARE_TYPEINFO
Marc Mutz
marc.mutz at kdab.com
Fri Jul 10 11:03:49 CEST 2015
Hi,
I'll never manage to eradicate inefficient QLists if people continue to add
new ones :) So here are some things I'd like _everyone_ to watch out for in
reviews and mercilessly -1:
- using QList
- not using Q_DECLARE_TYPEINFO
Let me qualify that a bit: QList<C> is a _very_ bad idea for virtually any C,
because the minutest of mistakes (and the default behaviour _is_ a mistake)
can render it utterly and unacceptably inefficient. I won't give you the whole
story (google "QList harmful" for that), but never, ever use QList<C>
*unless*:
- sizeof(C) == sizeof(void*) (*both* on 64 and 32-bit platforms!) _and_ C has
been declared Q_MOVABLE_TYPE or Q_PRIMITIVE_TYPE
-or-
- the use is unescapable, because other parts of Qt use it (e.g. QVariant,
QModelIndex).
The latter doesn't mean that you should _always_ use QList for QVariant or
QModelIndex. If all you're doing is local to your class, then by all means use
a QVector.
QVector is the correct default container. If you actually need list behaviour
(ie. linked lists), use QLinkedList instead. It tends to be _faster_ than
QList.
In private implementation, also consider using std::vector<C>, esp. if you
never copy it and C is (explictly or implicitly) move-enabled. It typically
produces up to 1KiB less executable code than QVector. *Per instantiation*.
If in *any* kind of doubt whether QList is acceptable, or any of your
container choices, feel free to add me as a reviewer.
And please, whenever you add a new type (not just class, *any* type, incl.
enums, but excluding QFlags (which are automatically primitive)), strongly
consider Q_DECLARE_METATYPE with the appropriate flag (yes, even
Q_COMPLEX_TYPE). About the only time this can be considered optional is for
polymorphic classes. It should become second nature to Q_DECLARE_TYPEINFO.
It should be considered a _must_ to Q_DECLARE_TYPEINFO any type that is put
into a QVector, QList or QVariant. In fact, my local copy enforces this at
compile-time. I hope to push this work at some point, but of course, that
means that each and every occurrence in Qt itself first needs to be fixed, and
even then, we can only enable it as an opt-in to not break user code (even if
it deserves to be broken).
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 Experts
More information about the Development
mailing list