[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 320
  • Last Modified:

Specifying a comparison function for a multiset

I was trying to specify an overloaded greater-than operator as a second parameter to an instantiation of a multiset.  I was expecting that I could specify MyClass::operator> but the compiler didn't like this.  Using greater<MyClass> worked.  This looks somewhat like a function template to me but I still don't understand why I had to use that instead of something that looked very much like the overloaded operator definition syntax (MyClass::operator>).  Can someone explain to me why I had to use the one and not the other?
0
iyac
Asked:
iyac
1 Solution
 
phoffricCommented:
If you could you post the code that does not compile in the Code box, that will provide a good starting point. Likewise (maybe as a separate post to keep them apart) could you post the code that does compile and work correctly.
0
 
pgnatyukCommented:
Overloading the comparison operators
http://www.learncpp.com/cpp-tutorial/94-overloading-the-comparison-operators/

Probably you forgot to make this operator "friend":
friend bool operator>(const MyClass& x, const MyClass& y);
0
 
evilrixSenior Software Engineer (Avast)Commented:
>> I was expecting that I could specify MyClass::operator> but the compiler didn't like this
You can't specify a predicate that is a class instance function. You need to provide a predicate functor. Below is a simple functor that implements lessThat (the formal predicate) for a multiset if int types. Use that as an example and modify to suit your needs.

http://www.cplusplus.com/reference/stl/multiset/
#include <set>

struct functor
{
   bool operator()(int lhs, int rhs) const // Change these types to suit
   {
      return (lhs < rhs); // Change this logic to suit
   }
};

int main()
{
   std::multiset<int, functor> mset;
}

Open in new window

0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
evilrixSenior Software Engineer (Avast)Commented:
Incidentally, if you class implements its own operator < () then you do not need to specify a predicate, it will automatically call the < operator and use it.

>> I still don't understand why I had to use that instead of something that looked very much like the overloaded operator definition syntax (MyClass::operator>).
You can't use the operator of a class instance because it has to be bound with a this pointer.
#include <set>

struct msettype
{
   bool operator < (msettype const & rhs) const
   {
      return (this->n < rhs.n);
   }

   int n;
};

int main()
{
   std::multiset<msettype> mset;
}

Open in new window

0
 
itsmeandnobodyelseCommented:
To add to above comments:

As mentioned from evilrix the second argument of multiset requires a "less-than" and not a "greater-than" compare function beside you want to sort in descending order. But if so, you shouldn't turn the functionality in operator< but provide a global (or static member) compare function for the multiset in order to not spoiling 'normal' comparisions.

Note, the functor evilrix showed above is a wonderful means to have a comparision which either sorts ascending or descending by simply adding a member to the functor class as sortmode:

class myfunctor
{
   bool ascending;
public:
   myfunctor() : ascending(true) {}
   myfunctor(bool asc_or_desc) : ascending(asc_or_desc) {}
   bool operator()(const myclass & lhs, const myclass & rhs) const
   {
        return ascending? (lhs < rhs) : (rhs < lhs);
   }
};

 // sort descending
 std::multiset<int, myfunctor(false) > mset;

 
0
 
evilrixSenior Software Engineer (Avast)Commented:
>> As mentioned from evilrix the second argument of multiset requires a "less-than" and not a "greater-than" compare
Actually, that's not what I said :) I said (probably not very clearly knowing me) it will call operator <() on the class if a sort predicate functor isn't provided.

Just to note, the functor is generally a less-than but it can be any predicate. For example, if you provide a greater-than it'll order in descending rather than ascending order. What I said is that it's a functor. The important thing is the behaviour is consistent so as to facilitate consistant key ordering.
0
 
Infinity08Commented:
Note that the functor shown by evilrix in http:#29310788 is basically the same is the standard less functor :

        http://www.cplusplus.com/reference/std/functional/less/

which is similar to the standard greater functor you were already using :

        http://www.cplusplus.com/reference/std/functional/greater/

I'd suggest to simply keep using the standard functors, unless you need different functionality ;)


Note also that the standard <functor> library provides functors for the other operators too - they come in very handy !
0
 
Infinity08Commented:
>> the standard <functor> library

typo there ... make that <functional> instead ;)
0
 
evilrixSenior Software Engineer (Avast)Commented:
>> Note that the functor shown by evilrix in http:#29310788 is basically the same is the standard less functor :
Agreed, but it was a coded example in case iyac wished to implement different logic to that of the standard less and greater predicates.

>> I'd suggest to simply keep using the standard functors, unless you need different functionalit
Agreed.
0

Featured Post

Get your problem seen by more experts

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

Tackle projects and never again get stuck behind a technical roadblock.
Join Now