> -----Original Message----- > From: [email protected] > [mailto:development-bounces+mitch.curtis=theqtcompany.com@qt- > project.org] On Behalf Of Marc Mutz > Sent: Friday, 10 July 2015 11:04 AM > To: [email protected] > Subject: [Development] HEADS UP: Don't use QList, use Q_DECLARE_TYPEINFO > > 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
I'm guessing that you meant to write Q_DECLARE_TYPEINFO here? For those (like me) wondering why Marc is advocating the use of this macro, it's briefly explained in the documentation [1]: "You can use this macro to specify information about a custom type Type. With accurate type information, Qt's generic containers can choose appropriate storage methods and algorithms. Flags can be one of the following: Q_PRIMITIVE_TYPE specifies that Type is a POD (plain old data) type with no constructor or destructor, or else a type where every bit pattern is a valid object and memcpy() creates a valid independent copy of the object. Q_MOVABLE_TYPE specifies that Type has a constructor and/or a destructor but can be moved in memory using memcpy(). Q_COMPLEX_TYPE (the default) specifies that Type has constructors and/or a destructor and that it may not be moved in memory." [1] http://doc.qt.io/qt-5/qtglobal.html#Q_DECLARE_TYPEINFO > 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 <[email protected]> | Senior Software Engineer > KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company > Tel: +49-30-521325470 > KDAB - The Qt Experts > _______________________________________________ > Development mailing list > [email protected] > http://lists.qt-project.org/mailman/listinfo/development _______________________________________________ Development mailing list [email protected] http://lists.qt-project.org/mailman/listinfo/development
