Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QList::value(int i) implementation question



  • This question could possibly be about documentation or C++ or Python. So i'm posting it here!

    Foreground to question:

    For the overload T QList::value(int i) const docs (https://doc.qt.io/qt-5/qlist.html#value) state

    If the index i is out of bounds, the function returns a default-constructed value.

    and https://doc.qt.io/qt-5/containers.html#default-constructed-value

    The documentation of certain container class functions refer to default-constructed values. [...] For most value types, this simply means that a value is created using the default constructor.

    I need to know whether the documentation is indeed correct in saying that QList::value(int i) will return such a "default constructed value" when i is out of range, and how it manages to do it when the type, T, is an abstract type?

    Background to question:

    QList<QLayoutItem *> itemList;
    
    QLayoutItem *FlowLayout::itemAt(int index) const
    {
        return itemList.value(index);
    }
    
    • I have verified that, for whatever reason, the Qt layout/widget framework does call my FlowLayout::itemAt(int index) when index is out of range (e.g. it calls it with index==0 even when my count() returns 0). So I do need to "emulate" the C++ "default constructor" return result.

    • In Python/PyQt you cannot use QList. You use the native list type, so that is what my itemList is. When index is in range Python itemList[index] works fine for C++ itemList.value(index). But when it's out of range I need to do what the C++ QList::value(out_of_range) would do, the "default constructor".

    • But the type of itemList is QList<QLayoutItem *>, and QLayoutItem is an abstract type. So my Python cannot go return QLayoutItem() to emulate, any more than you could in C++ --- I get a Python/PyQt run-time error saying "cannot create abstract instance/object".

    So how does QList::value() do it, and how can I? As I write this I have a feeling this might not be an issue in C++ because of how templates work, I don't know. (Maybe the code for value() can go new T(); and that works?) I haven't got templates, and the Python list I create for a QList doesn't have any type information in the way that QList<T> does.

    Anyone??



  • @JonB if T is an abstract type, it must be a pointer in C++, so the "default constructed value" will be a null pointer (nullptr) in this case.

    From https://doc.qt.io/qt-5/containers.html#default-constructed-value:

    But for primitive types like int and double, as well as for pointer types, the C++ language doesn't specify any initialization; in those cases, Qt's containers automatically initialize the value to 0.



  • @Gojir4
    That could be very helpful/good news for me!

    At present I think I shoved in return None to get past it crashing and it might be working, I wasn't sure. I'd be happy if all I have to do is return None for nullptr :)

    Do you know, I'm just looking at the code and thinking I was mistaken, I didn't look closely enough.... It's QList<QLayoutItem *> itemList; here. That's a list of pointers. I'm getting so used to irritating Python now, I think I thought it was QList<QLayoutItem> itemList;, no pointers, a list of QLayoutItems. One way or another I was thinking I had to create/return some ("empty") concrete instance of an QLayoutItem, maybe new T(), ....

    OK, this all makes sense now if I can just return nullptr for my default item!


Log in to reply