문제

From the docs:

Internally, QList is represented as an array of pointers to items of type T. If T is itself a pointer type or a basic type that is no larger than a pointer, or if T is one of Qt's shared classes, then QList stores the items directly in the pointer array.

I'm interested to know, how does QList 'decide' whether to store pointers or the items themselves depending on the type?

Do they do it using some esoteric template syntax?

도움이 되었습니까?

해결책

Let's read the source (I'm using Qt 4.8).

qlist.h:

struct Node { 
    void *v;
#if defined(Q_CC_BOR)
    Q_INLINE_TEMPLATE T &t();
#else
    Q_INLINE_TEMPLATE T &t()
    { return *reinterpret_cast<T*>(QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic
                                   ? v : this); }
#endif
};

QList uses QTypeInfo to determine type properties. QTypeInfo is declared for various types separately. In qglobal.h:

Default declaration for unknown type:

template <typename T>
class QTypeInfo
{
public:
    enum {
        isPointer = false,
        isComplex = true,
        isStatic = true,
        isLarge = (sizeof(T)>sizeof(void*)),
        isDummy = false
    };
};

Declaration for pointers:

template <typename T>
class QTypeInfo<T*>
{
public:
    enum {
        isPointer = true,
        isComplex = false,
        isStatic = false,
        isLarge = false,
        isDummy = false
    };
};

Macros for convenient type info declaration:

#define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS) \
class QTypeInfo<TYPE > \
{ \
public: \
    enum { \
        isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0), \
        isStatic = (((FLAGS) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), \
        isLarge = (sizeof(TYPE)>sizeof(void*)), \
        isPointer = false, \
        isDummy = (((FLAGS) & Q_DUMMY_TYPE) != 0) \
    }; \
    static inline const char *name() { return #TYPE; } \
}

#define Q_DECLARE_TYPEINFO(TYPE, FLAGS) \
template<> \
Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS)

Declaration for primitive types:

Q_DECLARE_TYPEINFO(bool, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(char, Q_PRIMITIVE_TYPE); /* ... */

Also it's defined for specific Qt types, e.g. in qurl.h:

Q_DECLARE_TYPEINFO(QUrl, Q_MOVABLE_TYPE);

Or in qhash.h:

Q_DECLARE_TYPEINFO(QHashDummyValue, Q_MOVABLE_TYPE | Q_DUMMY_TYPE);

When QList uses QTypeInfo<T>, the compiler picks up the closest of present QTypeInfo definitions.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top