iyac
asked on
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?
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.
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);
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);
>> 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/
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;
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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;
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;
>> 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.
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.
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 !
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 !
>> the standard <functor> library
typo there ... make that <functional> instead ;)
typo there ... make that <functional> instead ;)
>> 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.
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.