[Development] QList

Thiago Macieira thiago.macieira at intel.com
Sat Mar 25 22:13:04 CET 2017


On sábado, 25 de março de 2017 10:22:22 PDT Marc Mutz wrote:
> The main idea of QBasicVector is to fight template bloat by e.g. inheriting
> both QVector<const T> and QVector<T> from the same QBasicVector. Likewise,
> all QVector<T*> can inherit QBasicVector<const void*>. Or all QVector<T>,
> intergral_type<T> can inherit QBasicVector<QIntegerForSizeof<T>::Unsigned>,
> or all QVector<E>, is_enum<E>, from
> QBasicVector<QIntegerForSizeof<underlying_type_t<T>>::Unsigned>, or even
> QVector<T>, qt_is_refcounted<T> && sizeof(T) == sizeof(void*) :
> QBasicVector<QExplicitlySharedDataPointer<QSharedData>>...

I see what you mean. Yes, there's some code that can be shared and we should 
explore doing so. That's what QArrayDataOps is for, BTW: QPodArrayOps should 
help a lot. But unless we start moving things out-of-line, I don't think we'll 
reduce template bloat, as almost everything is inlined anyway, regardless of 
whether it's T* or void*; enum E or std::underlying_type<E>::type, etc.

> You can do this with composition, too. You don't even need QBasicVector. But
> if you e.g. want to collapse all QV<T*> to QV<const void*>, you need to
> either manually specialise QV<const void*> or use SFINAE so the T* case
> does not match const void*. Then you can aggregate a QV<const void*> in
> QV<T*> and delegate all functions there.

Right.

> You can also generally have QVector<T> _contain_ a QBasicVector<T>, and do
> the specialisation via a type trait:
> 
>   template <typename T>
>   class QVector {
>       using underlying_t = typename qvector_choose_underlying_for<T>::type;
>       QBasicVector<underlying_t> impl;
>       T* begin() { return reinterpret_cast<T*>
>                    (const_cast<std::remove_cv_t<underlying_t>*>
>                    (impl.begin())); }
>       // ...
>   }

Worth exploring, but my gut feeling says this will not help with code size, 
but will hinder maintenance.

> I have no idea how that plays with inlining, though. Maybe in the end this
> also turns into a case for using free functions to control inlining better.

Right. This only reduces code size if we do out-of-line work somewhere. That's 
why we have QListData, QArrayData, QMapData, etc. That's why Qt 1 had QGList, 
QGVector and QGArray, even.

> But all that said, all this specialisation stuff, all the types that want to
> inherit QVector because they are some form of collection of things, with no
> or little constraints added, and all these not-yet-mentioned uses of QBV to
> implement fast conversion from, say, QPolygon to QVector<QPoint>, even
> though they are unrelated, these all do not apply to QString.

This won't solve the MSVC problem. The only way to solve the MSVC problem is 
to stop the inheritance of an exported class from a non-exported (especially 
template!) one.

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




More information about the Development mailing list