Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Invalid comparator for STL map

Invalid comparator for STL map

Scheduled Pinned Locked Moved C / C++ / MFC
c++
13 Posts 4 Posters 0 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.
  • F Offline
    F Offline
    ForNow
    wrote on last edited by
    #1

    Hi I am getting invalid comparator for the following code and I just dont get it at the very end there is always a path to return

    struct usingrange
    {
    ESDID esdid;
    int start;
    int end;

    usingrange() { start = 0; end = 0; return; }
    

    bool operator<(const usingrange x) const {
    if (esdid <= x.esdid) return esdid <= x.esdid;
    if (start <= x.start) return start <= x.start; if (end <= x.end) return end <= x.end;
    else
    return FALSE;

    D 1 Reply Last reply
    0
    • F ForNow

      Hi I am getting invalid comparator for the following code and I just dont get it at the very end there is always a path to return

      struct usingrange
      {
      ESDID esdid;
      int start;
      int end;

      usingrange() { start = 0; end = 0; return; }
      

      bool operator<(const usingrange x) const {
      if (esdid <= x.esdid) return esdid <= x.esdid;
      if (start <= x.start) return start <= x.start; if (end <= x.end) return end <= x.end;
      else
      return FALSE;

      D Offline
      D Offline
      Daniel Pfeffer
      wrote on last edited by
      #2

      Shouldn't you be passing usingrange as a reference to your comparison function?

      bool operator<(const usingrange**&** x) const

      Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

      F 2 Replies Last reply
      0
      • D Daniel Pfeffer

        Shouldn't you be passing usingrange as a reference to your comparison function?

        bool operator<(const usingrange**&** x) const

        Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

        F Offline
        F Offline
        ForNow
        wrote on last edited by
        #3

        It’s a member of key type

        1 Reply Last reply
        0
        • D Daniel Pfeffer

          Shouldn't you be passing usingrange as a reference to your comparison function?

          bool operator<(const usingrange**&** x) const

          Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

          F Offline
          F Offline
          ForNow
          wrote on last edited by
          #4

          this is were I am getting the exception at the line with STL_VERIFY

          // FUNCTION TEMPLATE _Debug_lt_pred
          template , _Remove_cvref_t<_Ty2>>, int> = 0>
          constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept(
          noexcept(_Pred(_Left, _Right)) && noexcept(_Pred(_Right, _Left))) {
          // test if _Pred(_Left, _Right) and _Pred is strict weak ordering, when the arguments are the cv-same-type
          const auto _Result = static_cast(_Pred(_Left, _Right));
          if (_Result) {
          _STL_VERIFY(!_Pred(_Right, _Left), "invalid comparator");

          this is my code

          struct usingrange
          {
          ESDID esdid;
          int start;
          int end;

          usingrange() { start = 0; end = 0; return; }
          

          bool operator<(const usingrange& x) const {
          if (esdid < x.esdid)
          return esdid < x.esdid;
          if (start < x.start)
          return start < x.start;
          if (end < x.end) return end < x.end;
          else
          return x.end < end;

          when I change mt code to

          bool operator<(const usingrange& x) const {

           return start < x.start;
          

          }

          everything works I dont get it the operator is excepting a bool retrun code true or false in either I retrun that

          G 1 Reply Last reply
          0
          • F ForNow

            this is were I am getting the exception at the line with STL_VERIFY

            // FUNCTION TEMPLATE _Debug_lt_pred
            template , _Remove_cvref_t<_Ty2>>, int> = 0>
            constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept(
            noexcept(_Pred(_Left, _Right)) && noexcept(_Pred(_Right, _Left))) {
            // test if _Pred(_Left, _Right) and _Pred is strict weak ordering, when the arguments are the cv-same-type
            const auto _Result = static_cast(_Pred(_Left, _Right));
            if (_Result) {
            _STL_VERIFY(!_Pred(_Right, _Left), "invalid comparator");

            this is my code

            struct usingrange
            {
            ESDID esdid;
            int start;
            int end;

            usingrange() { start = 0; end = 0; return; }
            

            bool operator<(const usingrange& x) const {
            if (esdid < x.esdid)
            return esdid < x.esdid;
            if (start < x.start)
            return start < x.start;
            if (end < x.end) return end < x.end;
            else
            return x.end < end;

            when I change mt code to

            bool operator<(const usingrange& x) const {

             return start < x.start;
            

            }

            everything works I dont get it the operator is excepting a bool retrun code true or false in either I retrun that

            G Offline
            G Offline
            Graham Breach
            wrote on last edited by
            #5

            Does your ESDID class have an operator<() function? If not, add one.

            F 2 Replies Last reply
            0
            • G Graham Breach

              Does your ESDID class have an operator<() function? If not, add one.

              F Offline
              F Offline
              ForNow
              wrote on last edited by
              #6

              Thank you so much actually everything is a structure I am a very open :) person I got to tell you something you C++ guys a geniuses

              1 Reply Last reply
              0
              • G Graham Breach

                Does your ESDID class have an operator<() function? If not, add one.

                F Offline
                F Offline
                ForNow
                wrote on last edited by
                #7

                still getting the exception if the key to the map is a structure consisting of a char[4] and 2 int how would I set < operator the only way I got it to work was by return int1 < x.int1 what would like to do is concatenate all of them in 12 bytes and compare 12 bytes against 12 bytes thanks

                F 2 Replies Last reply
                0
                • F ForNow

                  still getting the exception if the key to the map is a structure consisting of a char[4] and 2 int how would I set < operator the only way I got it to work was by return int1 < x.int1 what would like to do is concatenate all of them in 12 bytes and compare 12 bytes against 12 bytes thanks

                  F Offline
                  F Offline
                  ForNow
                  wrote on last edited by
                  #8

                  Since my the total of my data was 12 bytes I was lucky there happened to be a data type 16 bytes long double just filled first 4 bytes with zeros and here is the code

                  struct usingrange
                  {
                  ESDID esdid;
                  int start;
                  int end;

                  usingrange() { start = 0; end = 0; return; }
                  

                  bool operator<(const usingrange& x) const {
                  union
                  {
                  long double a;
                  char str1[16];
                  }c;
                  union
                  {
                  long double b;
                  char str2[16];
                  }d;

                    ::memset(&c.str1, 0x00, 16);
                    ::memset(&d.str2, 0x00, 16);
                    ::memcpy(&c.str1\[4\], &esdid, 4);
                    ::memcpy(&c.str1\[8\],&start,4);
                    ::memcpy(&c.str1\[12\], &end, 4);
                    ::memcpy(&d.str2\[4\], &x.esdid, 4);
                    ::memcpy(&d.str2\[8\], &x.start, 4);
                    ::memcpy(&d.str2\[12\], &x.end, 4);
                  
                    return c.a < d.b;
                  
                  //	  return usingrange  < x;
                  //	  if (start < x.start) 
                   //   return start < x.start;
                  

                  // return x.end < end;

                  }

                  };

                  1 Reply Last reply
                  0
                  • F ForNow

                    still getting the exception if the key to the map is a structure consisting of a char[4] and 2 int how would I set < operator the only way I got it to work was by return int1 < x.int1 what would like to do is concatenate all of them in 12 bytes and compare 12 bytes against 12 bytes thanks

                    F Offline
                    F Offline
                    ForNow
                    wrote on last edited by
                    #9

                    Since my data was 12 bytes long I was lucky there happened to be a data type 16 bytes long a "long double" I just filled the first 4 bytes with zeros and

                    ;
                    struct usingrange
                    {
                    ESDID esdid;
                    int start;
                    int end;

                    usingrange() { start = 0; end = 0; return; }
                    

                    bool operator<(const usingrange& x) const {
                    union
                    {
                    long double a;
                    char str1[16];
                    }c;
                    union
                    {
                    long double b;
                    char str2[16];
                    }d;

                      ::memset(&c.str1, 0x00, 16);
                      ::memset(&d.str2, 0x00, 16);
                      ::memcpy(&c.str1\[4\], &esdid, 4);
                      ::memcpy(&c.str1\[8\],&start,4);
                      ::memcpy(&c.str1\[12\], &end, 4);
                      ::memcpy(&d.str2\[4\], &x.esdid, 4);
                      ::memcpy(&d.str2\[8\], &x.start, 4);
                      ::memcpy(&d.str2\[12\], &x.end, 4);
                    
                      return c.a < d.b;
                    
                    //	  return usingrange  < x;
                    //	  if (start < x.start) 
                     //   return start < x.start;
                    

                    // return x.end < end;

                    }

                    };

                    K G 2 Replies Last reply
                    0
                    • F ForNow

                      Since my data was 12 bytes long I was lucky there happened to be a data type 16 bytes long a "long double" I just filled the first 4 bytes with zeros and

                      ;
                      struct usingrange
                      {
                      ESDID esdid;
                      int start;
                      int end;

                      usingrange() { start = 0; end = 0; return; }
                      

                      bool operator<(const usingrange& x) const {
                      union
                      {
                      long double a;
                      char str1[16];
                      }c;
                      union
                      {
                      long double b;
                      char str2[16];
                      }d;

                        ::memset(&c.str1, 0x00, 16);
                        ::memset(&d.str2, 0x00, 16);
                        ::memcpy(&c.str1\[4\], &esdid, 4);
                        ::memcpy(&c.str1\[8\],&start,4);
                        ::memcpy(&c.str1\[12\], &end, 4);
                        ::memcpy(&d.str2\[4\], &x.esdid, 4);
                        ::memcpy(&d.str2\[8\], &x.start, 4);
                        ::memcpy(&d.str2\[12\], &x.end, 4);
                      
                        return c.a < d.b;
                      
                      //	  return usingrange  < x;
                      //	  if (start < x.start) 
                       //   return start < x.start;
                      

                      // return x.end < end;

                      }

                      };

                      K Offline
                      K Offline
                      k5054
                      wrote on last edited by
                      #10

                      That has a couple of issues. Firstly, you are invoking undefined behavior: [Union declaration - cppreference.com](https://en.cppreference.com/w/cpp/language/union#:~:text=It is undefined behavior to read from the member of the union that wasn't most recently written. Many compilers implement%2C as a non-standard language extension%2C the ability to read inactive members of a union.) Secondly, you're expecting that the bit patterns of 2 doubles can be compared. This may not be the case, as you may a NaN this way, and then any comparison will return false:

                      [k5054@localhost tmp]$ cat example.c
                      #include

                      int main()
                      {
                      double d = 0.0 / 0.0; // produces NaN
                      printf("1.0 < d = %d\n", 1.0 < d);
                      printf("d < 1.0 = %d\n", d < 1.0);
                      printf("d == d = %d\n", d == d);
                      }
                      [k5054@localhost tmp]$ gcc example.c -o example
                      [k5054@localhost tmp]$ ./example
                      1.0 < d = 0
                      d < 1.0 = 0
                      d == d = 0
                      [k5054@localhost tmp]$

                      As we can see in the above code, NaN compared to anything, even itself returns false. If all you want to do is compare bits, you might as well just go ahead and use memcmp()

                      *#35;include
                      struct usingrange {
                      ESDID esdid;
                      int start;
                      int end;
                      // ... other stuff ...
                      bool operator<(const usingrange& x)const {
                      return ::memcmp(this, &x, sizeof(*this)
                      }
                      };

                      This relies on the fact that the sizeof a struct or a class is the size of its individual members. This only becomes tricky if your struct/class includes STL or other objects like std::string or std::vector.

                      Keep Calm and Carry On

                      F 1 Reply Last reply
                      0
                      • K k5054

                        That has a couple of issues. Firstly, you are invoking undefined behavior: [Union declaration - cppreference.com](https://en.cppreference.com/w/cpp/language/union#:~:text=It is undefined behavior to read from the member of the union that wasn't most recently written. Many compilers implement%2C as a non-standard language extension%2C the ability to read inactive members of a union.) Secondly, you're expecting that the bit patterns of 2 doubles can be compared. This may not be the case, as you may a NaN this way, and then any comparison will return false:

                        [k5054@localhost tmp]$ cat example.c
                        #include

                        int main()
                        {
                        double d = 0.0 / 0.0; // produces NaN
                        printf("1.0 < d = %d\n", 1.0 < d);
                        printf("d < 1.0 = %d\n", d < 1.0);
                        printf("d == d = %d\n", d == d);
                        }
                        [k5054@localhost tmp]$ gcc example.c -o example
                        [k5054@localhost tmp]$ ./example
                        1.0 < d = 0
                        d < 1.0 = 0
                        d == d = 0
                        [k5054@localhost tmp]$

                        As we can see in the above code, NaN compared to anything, even itself returns false. If all you want to do is compare bits, you might as well just go ahead and use memcmp()

                        *#35;include
                        struct usingrange {
                        ESDID esdid;
                        int start;
                        int end;
                        // ... other stuff ...
                        bool operator<(const usingrange& x)const {
                        return ::memcmp(this, &x, sizeof(*this)
                        }
                        };

                        This relies on the fact that the sizeof a struct or a class is the size of its individual members. This only becomes tricky if your struct/class includes STL or other objects like std::string or std::vector.

                        Keep Calm and Carry On

                        F Offline
                        F Offline
                        ForNow
                        wrote on last edited by
                        #11

                        The return using memcmp as operands will get an exception in order to get around this I need to to have to have the syntax return operand1 < operand2 truthfully the order of the items is not that important as long as I am able to retrieve the data by key thanks

                        1 Reply Last reply
                        0
                        • F ForNow

                          Since my data was 12 bytes long I was lucky there happened to be a data type 16 bytes long a "long double" I just filled the first 4 bytes with zeros and

                          ;
                          struct usingrange
                          {
                          ESDID esdid;
                          int start;
                          int end;

                          usingrange() { start = 0; end = 0; return; }
                          

                          bool operator<(const usingrange& x) const {
                          union
                          {
                          long double a;
                          char str1[16];
                          }c;
                          union
                          {
                          long double b;
                          char str2[16];
                          }d;

                            ::memset(&c.str1, 0x00, 16);
                            ::memset(&d.str2, 0x00, 16);
                            ::memcpy(&c.str1\[4\], &esdid, 4);
                            ::memcpy(&c.str1\[8\],&start,4);
                            ::memcpy(&c.str1\[12\], &end, 4);
                            ::memcpy(&d.str2\[4\], &x.esdid, 4);
                            ::memcpy(&d.str2\[8\], &x.start, 4);
                            ::memcpy(&d.str2\[12\], &x.end, 4);
                          
                            return c.a < d.b;
                          
                          //	  return usingrange  < x;
                          //	  if (start < x.start) 
                           //   return start < x.start;
                          

                          // return x.end < end;

                          }

                          };

                          G Offline
                          G Offline
                          Graham Breach
                          wrote on last edited by
                          #12

                          I think you're making it too complicated:

                          struct ESDID
                          {
                          char c[4];

                          bool operator<(const ESDID& other) const
                          {
                          return c[0] < other.c[0] && c[1] < other.c[1] &&
                          c[2] < other.c[2] && c[3] < other.c[3];
                          }
                          }

                          struct usingrange
                          {
                          ESDID esdid;
                          int start;
                          int end;

                          bool operator<(const usingrange& other) const
                          {
                          return esdid < other.esdid && start < other.start &&
                          end < other.end;
                          }
                          }

                          I've used && and < because you do not want operator<() to return true for two different objects when you swap them around.

                          F 1 Reply Last reply
                          0
                          • G Graham Breach

                            I think you're making it too complicated:

                            struct ESDID
                            {
                            char c[4];

                            bool operator<(const ESDID& other) const
                            {
                            return c[0] < other.c[0] && c[1] < other.c[1] &&
                            c[2] < other.c[2] && c[3] < other.c[3];
                            }
                            }

                            struct usingrange
                            {
                            ESDID esdid;
                            int start;
                            int end;

                            bool operator<(const usingrange& other) const
                            {
                            return esdid < other.esdid && start < other.start &&
                            end < other.end;
                            }
                            }

                            I've used && and < because you do not want operator<() to return true for two different objects when you swap them around.

                            F Offline
                            F Offline
                            ForNow
                            wrote on last edited by
                            #13

                            just tried it that did it thank you :)

                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups