Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to overload operator< for QVector3D class

How to overload operator< for QVector3D class

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 3 Posters 705 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    m3g1dd
    wrote on last edited by m3g1dd
    #1

    I'm using QVector3d with std::set and std::hypot. I'm receiving this error:

    /usr/include/c++/7/bits/stl_function.h:386:
    
    error: no operator "<" matches these operands
    
    operand types are: const QVector3D < const QVector3D
    
    { return __x < __y; }
    

    Is there a way to implement an overloaded operator< for QVector3D? I mean, without the need to compile all Qt from source!

    1 Reply Last reply
    0
    • Kent-DorfmanK Offline
      Kent-DorfmanK Offline
      Kent-Dorfman
      wrote on last edited by Kent-Dorfman
      #2

      std::set is a sorted associative set, which means it is created with a default predicate function of less_than or having (x<y) operator defined. The Qt QSet is an unsorted set and only uses the == operator to check if an item is already inserted in the set. Either switch to using QSet, or define a friend function for QVector3D::operator<(const QVector3D&) so that ordering of the vectors can take place.

      Actually you would subclass QVector3D, provide the operator overload for the subclass, and then you could use std::set<subclass>

      If you meet the AI on the road, kill it.

      1 Reply Last reply
      3
      • M Offline
        M Offline
        m3g1dd
        wrote on last edited by
        #3

        I just replaced this:

        std::set<QVector3D> band{ *first, *last };
        

        with

        auto customComparator = [](QVector3D const &a, QVector3D const &b) { return a.y() < b.y(); };
        std::set<QVector3D, decltype (customComparator)> band({ *first, *last }, customComparator);
        

        then the error got resolved.

        Kent-DorfmanK 1 Reply Last reply
        4
        • M m3g1dd

          I just replaced this:

          std::set<QVector3D> band{ *first, *last };
          

          with

          auto customComparator = [](QVector3D const &a, QVector3D const &b) { return a.y() < b.y(); };
          std::set<QVector3D, decltype (customComparator)> band({ *first, *last }, customComparator);
          

          then the error got resolved.

          Kent-DorfmanK Offline
          Kent-DorfmanK Offline
          Kent-Dorfman
          wrote on last edited by
          #4

          @m3g1dd

          That works too, more elegantly than subclassing QVector3D just to add an operator.

          If you meet the AI on the road, kill it.

          1 Reply Last reply
          0
          • W Offline
            W Offline
            wrosecrans
            wrote on last edited by
            #5

            Trying to put a three dimensional vector type into a sorted data structure is almost certainly the wrong thing to want to do. Because three dimensional vectors can't be sorted in a useful way. It's the reason that (two dimensional) imaginary numbers can't be put on a one-dimensional number line, but then with an extra third dimension of nonsortability thrown in to be sure. My best guess is that if you try to use the "{ return a.y() < b.y(); };" custom comparator lambda, you will run into the problem that different vectors with the same Y coordinate will be rejected from the data structure. So trying to store (0,0,0), (1,0,0), (2,0,0) will leave you with only one vector in the std::set. It'll make the compile error go away, but only by creating wildly counterintuitive semantic problems.

            If you reeeeeeeally want to sort 3D vectors (of any sort, not just the QVector3D class specifically) then I'd suggest you look up space-filling curves and use the morton encoding of the position of the vector, since morton encoded vectors can be ordered. The ordering is almost completely arbitrary for most use cases, but it is ordered. (But, again, this is almost certainly the wrong thing to want to do in the first place.)

            If you use std::unordered_set instead of std::set, you can bypass the sorting issue.

            1 Reply Last reply
            1

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved