从文档:
在内部,QList 表示为指向 T 类型项目的指针数组。如果 T 本身是指针类型或不大于指针的基本类型,或者如果 T 是 Qt 的共享类之一,则 QList 存储项目直接在指针数组中。
我很想知道,如何QList根据类型“决定”是存储指针还是存储项目本身?
他们是否使用一些深奥的模板语法来做到这一点?
让我们阅读源代码(我使用的是 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用于QTypeInfo确定类型属性。QTypeInfo分别为各种类型声明。在qglobal.h 中:
未知类型的默认声明:
template <typename T>
class QTypeInfo
{
public:
    enum {
        isPointer = false,
        isComplex = true,
        isStatic = true,
        isLarge = (sizeof(T)>sizeof(void*)),
        isDummy = false
    };
};
指针声明:
template <typename T>
class QTypeInfo<T*>
{
public:
    enum {
        isPointer = true,
        isComplex = false,
        isStatic = false,
        isLarge = false,
        isDummy = false
    };
};
用于方便类型信息声明的宏:
#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)
原始类型的声明:
Q_DECLARE_TYPEINFO(bool, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(char, Q_PRIMITIVE_TYPE); /* ... */
它还为特定的 Qt 类型定义,例如在qurl.h中:
Q_DECLARE_TYPEINFO(QUrl, Q_MOVABLE_TYPE);
或在qhash.h中:
Q_DECLARE_TYPEINFO(QHashDummyValue, Q_MOVABLE_TYPE | Q_DUMMY_TYPE);
使用时,编译QList器QTypeInfo<T>会选择最接近的当前QTypeInfo定义。