std::map comparator

struct type {
   uint32_t a;
   uint32_t b;
   uint32_t c;
   uint32_t d;
   };

std::map<type, uint32_t>my_map;

operator<(const type& n1, const type& n2) {
     if (n1.a < n2.a)
        return true;
     if (n1.a > n2.a)
        return false;
     if (n1.b < n2.b)
        return true;
     if (n1.b > n2.b)
        return false;
     if (n1.c < n2.c)
        return true;
     if (n1.c > n2.c)
        return false;
     if (n1.d < n2.d)
        return true;
     if (n1.d > n2.d)
        return false;

     return false;
}

Open in new window


Is there a better way of writing < comparator then the one I wrote. The above looks ugly and lengthy. I mean is there a shorter way of writing this by Boost or something else?
perlperlAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

chaauCommented:
If you want a shorter statement how about this:

operator<(const type& n1, const type& n2) {
     return !(n1.a < n2.a || n1.b < n2.b || n1.c < n2.c || n1.d < n2.d);
}

Open in new window


Will it be more readable than yours? I don't think so.
0
sarabandeCommented:
you can/should add the operator< as member to the struct:

struct type {
   uint32_t a;
   uint32_t b;
   uint32_t c;
   uint32_t d;

   bool operator<(const type& t)
   {
         return (a < t.a) || 
                     (a == t.a && b < t.b) ||
                     (a == t.a && b == t.b && c < t.c) ||
                     (a == t.a && b == t.b && c == t.c && d <= t.d);

   }
};

Open in new window



Sara
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
perlperlAuthor Commented:
chaau, I don't think so your one liner handles all the case, it ignores the case of "=="
I am sure there might be a fancy way to do this using boost, just couldn't find it :)
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

perlperlAuthor Commented:
1) Also why do I have to include all the members of structure in < comparator.
Why can't I just write  
return (a < t.a) ;

2) Also do we always have to overload < operator for struct or class as Key of std::map.

3) When do we overload () operator or == or !=
0
sarabandeCommented:
Why can't I just write  
return (a < t.a) ;

of course you can do. but than two entries t1 and t2 where t1.a == t2.a are equal. if you don't have such entries (what means that member a is key), i wonder why your map has struct type as key and not only uint32_t for the a member of the type.

note, a map needs to have a unique key.

Sara
0
perlperlAuthor Commented:
the members of my type are not unique. Two entries can have same few members, when I combine all members, they are considered unique.

now I got it, just to make sure the key is unique, I need to include all my members.
0
sarabandeCommented:
to make the comparision easier you could convert the a, b, c, d to a hex string and then compare the strings:

struct type {
   uint32_t a;
   uint32_t b;
   uint32_t c;
   uint32_t d;

   std::string uToHex(uint32_t u)
   {
        std::ostringstream os;
        os << std::hex << std::right << std::setfill('0') << std::setw(8) << (unsigned int)u;
        return os.str();
   }
   bool operator<(const type& t)
   {
        std::ostringstream os1, os2;
        os1 << uToHex(a) << uToHex(b)<< uToHex(c)<< uToHex(d);
        os2 << uToHex(t.a) << uToHex(t.b)<< uToHex(t.c)<< uToHex(t.d);
        return os1.str() < os2.str();
  }
  ...

Open in new window


2) Also do we always have to overload < operator for struct or class as Key of std::map.


you can pass a compare function or a functor as 3rd template argument to your map. but actually it doesn't make it easier. a key for a map always needs to have the same compare function. so if the key is a class or struct type you always should provide an operator<. in case of pointers, it is different.

3) When do we overload () operator or == or !=
operator() for example was overloaded for a functor. a functor was a helper class which - shortly said - provides a function pointer by means of operator() overload.
another usage for operator() is for example a string class where you do

MyString str = another_string(1, 2);

Open in new window


and where operator() would provide substring functionality.

operator!= should be overloaded if you have operator== overloaded. note, std::map doesn't need operator== cause it could find out equality by use of less function: !((a < b) || (b < a)).

you would provide operator== for your class or struct when you need the operation for your own purposes.

Sara
0
perlperlAuthor Commented:
ok. I was asking overloading with respect to std::map key (where key is struct or class)

so basically for map, we don't have to overload () or != or ==

just overloading '<' would be suffice for insert() and find() method on map ??
0
phoffricCommented:
>> os << std::hex << std::right << std::setfill('0') << std::setw(8) << (unsigned int)u;
If performance is any concern, then this will cause multiple time-consuming allocations.
0
sarabandeCommented:
yes. the operator< is sufficient.

Sara
0
chaauCommented:
@perlperl: my one liner handles == just well. It returns false like an original operator. Just FYI. As I mentioned it is less readable, but it does the job
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.