1

ドキュメントから:

内部的には、QList は T 型の項目へのポインターの配列として表されます。T 自体がポインター型またはポインター以下の基本型である場合、または T が Qt の共有クラスの 1 つである場合、QList は項目を格納します。ポインタ配列に直接。

QListタイプに応じて、ポインターまたはアイテム自体を保存するかどうかをどのように「決定」するのですか?

彼らはいくつかの難解なテンプレート構文を使用してそれを行いますか?

4

1 に答える 1

2

ソースを読んでみましょう (私は 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
};

QListQTypeInfoタイプ プロパティを決定するために使用します。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); /* ... */

また、 qurl.hなどの特定の Qt タイプに対しても定義されています。

Q_DECLARE_TYPEINFO(QUrl, Q_MOVABLE_TYPE);

またはqhash.hで:

Q_DECLARE_TYPEINFO(QHashDummyValue, Q_MOVABLE_TYPE | Q_DUMMY_TYPE);

QList使用するQTypeInfo<T>と、コンパイラは現在のQTypeInfo定義に最も近いものを選択します。

于 2013-07-08T11:22:08.487 に答える