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

How to specialize operator< on QPair or QSet for a certain class?



  • Hello,
    I'm using a QPair<Element*, QSet<Element*>> that I put in a QSet and use as key of a QMap.

    I've a compilation issue:

    /opt/Qt5.5.1/5.5/gcc_64/include/QtCore/qpair.h:109: error: no match for 'operator<' (operand types are 'const QSet<Element*>' and 'const QSet<Element*>')
         Q_DECL_NOEXCEPT_EXPR(noexcept(p1.first < p2.first || (!(p2.first < p1.first) && p1.second < p2.second)))
    

    Hum ok, so I'm trying to specialize the operator< in the Header of my Element class like this:

    template <> bool operator< (const QPair<Element*, QSet<Element*>> &p1,
                               const QPair<Element*, QSet<Element*>> &p2)
    {
        return p1.first < p2.first || (!(p2.first < p1.first) && p1.second.size() < p2.second.size());
    }
    

    But it is still picking the generic one in qpair.h
    How can I do?

    PS: I've seen there are several syntaxes to specialize a template function, I don't manage to compile with the one without argument deduction. (number 3 here: https://stackoverflow.com/questions/8323530/c-templates-specialization-syntax) The < of the operator< seems to be the problem.

    PS2: if I remove the template<> like I was overloading the function I get a mulitple definition issue

     error: multiple definition of `operator<(QPair<Element*, QSet<Element*> > const&, QPair<Element*, QSet<Element*> > const&)'
    


    • You don't need a template at all, just a global function declared in a header you include
    • p1.first < p2.first this compares the position in memory of those elements, I don't think it's what you want
    bool operator<(const QPair<Element*, QSet<Element*> > &p1, const QPair<Element*, QSet<Element*> > &p2)
    {
        return (*p1.first < *p2.first ? true : p1.second.size() < p2.second.size());
    }
    


  • @VRonin
    as I said, when I do that I get a multiple definition error.

    error: multiple definition of `operator<(QPair<Element*, QSet<Element*> > const&, QPair<Element*, QSet<Element*> > const&)'
    

    I guess this is due to the generated one by the QPair template...

    PS: I don't mind the order, and thus comparing the memory address for my first member, I just care about uniqueness


  • Qt Champions 2019

    When it is in the header it needs to be inline to avoid the problem with multiple definitions. Or move it to the source file and only leave the declaration in the header.



  • @Christian-Ehrlicher
    Thanks a lot, indeed it was just the inline keyword that was missing!


Log in to reply