Equality in QMap - operator== doesn't get invoked?



  • I have a custom class that I serialize into QVariant, which I then store in a QMap.
    QMap's documentation states:

    Returns true if other is equal to this map; otherwise returns false.
    Two maps are considered equal if they contain the same (key, value) pairs.
    This function requires the value type to implement operator==().

    So I assumed that the operator== of my type would be called, but when I put breakpoints into it, or debug statements, the debugger doesn't stop there, nor do the debug statements get printed out.

    edit: And this is even though I've called QMetaType::registerEqualsComparator() on my custom type.

    Any ideas? Thank you!


  • Qt Champions 2016

    @tmladek
    Hi,
    Here's the implementation. It should be working normally. Can you show a minimal snippet that reproduces the behavior you're experiencing?

    Kind regards.



  • Hm, it seems like it's actually in the fact that it's a QList. Anyway.

    #include <QCoreApplication>
    #include <QVariant>
    #include <QMap>
    #include <QMetaType>
    #include <QDataStream>
    #include <QDebug>
    
    struct Cat {
        QString name;
        QString color;
        bool operator==(const Cat &other) const;
    }; Q_DECLARE_METATYPE(Cat)
    
    bool Cat::operator==(const Cat &other) const {
        if (this->name != other.name) return false;
        if (this->color != other.color) return false;
        return true;
    }
    
    QDataStream &operator<<(QDataStream &out, const Cat &obj) {
        out << obj.name << obj.color;
        return out;
    }
    QDataStream &operator>>(QDataStream &in, Cat &obj) {
        in >> obj.name >> obj.color;
        return in;
    }
    
    int main(int argc, char *argv[])
    {
        qRegisterMetaType<Cat>("Cat");
        qRegisterMetaTypeStreamOperators<Cat>("Cat");
        QMetaType::registerEqualsComparator<Cat>();
    
        Cat cat_1;
        cat_1.name = "Bob";
        cat_1.color = "black";
        QList<Cat> list_1;
        list_1.append(cat_1);
        QVariant variant_1 = QVariant::fromValue(list_1);
        QMap<QString, QVariant> map_1;
        map_1.insert("cat", variant_1);
    
        Cat cat_2;
        cat_2.name = "Bob";
        cat_2.color = "black";
        QList<Cat> list_2;
        list_2.append(cat_2);
        QVariant variant_2 = QVariant::fromValue(list_2);
        QMap<QString, QVariant> map_2;
        map_2.insert("cat", variant_2);
    
        qDebug() << (list_1 == list_2) << (map_1 == map_2);
    }
    

    Outputs true false.


  • Qt Champions 2016

    @tmladek
    You are comparing QVariants that contain QList<Cat>, so you need to provide registered comparison operator for QList<Cat> (or conversions might take place), which you don't do.

    PS.
    Also, this:

    qRegisterMetaType<Cat>("Cat");
    

    should be:

    qRegisterMetaType<Cat>(); 
    

    as specifically mentioned in the documentation.


Log in to reply
 

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