QList: Convenient way to deep copy a pointer list?



  • Let's say I have a list of pointers, like so:
    QList<MyObject*> list;

    MyObject has a valid copy constructor and assignment operator.
    Is there a simple way to create a new list that is a deep copy of 'list'?

    Something like this:
    QList<MyObject*> copyOfList = qDeepCopy(list);


  • Qt Champions 2016

    Hi
    What does using operator = yield?
    http://doc.qt.io/qt-5/qlist.html#operator-eq



  • @mrjj said in QList: Convenient way to deep copy a pointer list?:

    Hi
    What does using operator = yield?
    http://doc.qt.io/qt-5/qlist.html#operator-eq

    Depending on whether the type is marked as moveable or not, it either calls the copy constructor of T (the copy constructor of a pointer thus copying the pointer - not the content), or std::move or memcpy...the code gets a little complex there.


  • Qt Champions 2016

    Oh so in the other copy of the list,
    it should not point to same T* but create new instances (of T) and change the new list to point to these?
    Sorry, that im pretty sure you must implement yourself. :)

    You could derive from QList and make overloaded = that does it for you but
    might be overkill.

    If MyObject is QObject based, you might get issues cloning them but I assume newing it / copy ctor is
    already working ?


  • Moderators

    @mrjj said in QList: Convenient way to deep copy a pointer list?:

    You could derive from QList and make overloaded = that does it for you but
    might be overkill.

    no need to. QList internally uses template methods. So implementing those methods directly for the custom type is already enough.

    Unfortunately i can't tell you what the correct settings are, since i don't have time to check it in the sources right now.
    But the first thing to change the behavior of QList is to generate QTypeInfo and the QList::node_construct():

    template <>
    class QTypeInfo<MyType>
    {
    public:
        enum {
            isPointer = true,
            isComplex = true,
            isStatic = false,
            isLarge = false,
            isDummy = false
        };
        static inline const char *name() { return "MyType"; }
    };
    
    template <>
    Q_INLINE_TEMPLATE void QList<MyType>::node_construct(Node *n, const MyType &t)
    {
        if (QTypeInfo<EyeOmsVariant>::isComplex)
                new (n) MyType(t);
        else
             ::memcpy(n, &t, sizeof(MyType));
    }
    

    Add something like this (implement it correctly) and the compiler will use them, instead creating them on-the-fly when needed.
    (read on C++ templates for details).



  • Thanks, but this is indeed overkill for my use case. I was hoping for an existing template method in the veins of qDeleteAll. If I come across this more often, I'll write it myself.

    BTW I wouldn't do type-specific template overloading in this case. Who says that I always want to deep-copy a pointer list of a certain type? But it's an interesting approach, I didn't think of that. Thanks again!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.