1

Do anyone know a general method to declare a comparision function for struct so that I can use it in sort , priority queue , map ,set ...

I would also know how to specify the comparision function when declaring a data structure (like map ) having a structure as a key (in the case where i have two or more comparision functions)

Thank you in advance

  • What should a "general method" to compare structs look like? `std::tie` is a good option for quickly defining comparisons. – TartanLlama Jul 24 '15 at 08:54

3 Answers3

1

How can the method be "general"?

Let's say you have this struct.

struct MyStruct{
    A a; // A is your own class
};

How would the compiler know how to compare objects of type A?

You need to define a comparison operator yourself.

bool operator()(const MyStruct& s1, const MyStruct& s2);

This function can be given as a compare-function when creating for example a std::map.

explicit map (const key_compare& comp = key_compare(),
          const allocator_type& alloc = allocator_type());

std::map

comp: Binary predicate that, taking two element keys as argument, returns true if the first argument goes before the second argument in the strict weak ordering it defines, and false otherwise.

defaults to

less<key_type>
jensa
  • 2,792
  • 2
  • 21
  • 36
  • hello i tried this code but i had an error saying that the comparing fuction must have only one argument – Mohamed Fadhel Omar Jul 24 '15 at 09:09
  • Then you´re doing something incorrectly. Can you post the code where you try to use it? It should be a binary predicate taking TWO arguments. – jensa Jul 24 '15 at 09:11
  • 1
    If you implement the operator as a member function it takes only one argument. If you implement it as an external function (friend) then it takes two. – aslg Jul 24 '15 at 09:17
  • It doesn't have to be a friend, members are public by default in structs. – jensa Jul 24 '15 at 09:19
  • i changed the place of the function (out of the struct ) and it worked , do you to have more than one function ? – Mohamed Fadhel Omar Jul 24 '15 at 09:25
  • No, you only give one function as the binary predicate. This function defines the strict weak ordering of the object type (in this case your struct). – jensa Jul 24 '15 at 09:51
0

The comparison function depends from the semantics of your struct. What does it mean that a < b for your type?

In general, a compare function is something along the line of this (references are optional):

bool comp( const YourType& a, const YourType& b );

To make a map use your compare function, you must write like this:

#include <map>

struct YourType{
    int v;
};

struct YourTypeComparison{
    bool operator()( const YourType& a, const YourType& b ) { return a.v < b.v; }
};

int main()
{
    std::map<YourType,int, YourTypeComparison> m;
}
Paolo M
  • 12,403
  • 6
  • 52
  • 73
  • hello thank you for your answer i does work with map , but it seems not to work whith priority queue here is my declaration : std::priority_queue,YourTypeComparison> m; – Mohamed Fadhel Omar Jul 24 '15 at 09:19
  • @MohamedFadhelOmar It compiles fine to me. Have you included and ? And try to write std::priority_queue,YourTypeComparison> m; (note the std:: before "vector") – Paolo M Jul 24 '15 at 09:24
  • @MohamedFadhelOmar You are wellcome! You may want to accept the answer ;) – Paolo M Jul 24 '15 at 09:31
0

Normally you would use the standard containers like std::map< std::string, int >. But they also have a Comparator type and an Allocator type.

The Comparator used by default is std::less, which looks somewhat like this,

template <class T>
struct less : binary_function <T,T,bool> {
    bool operator() (const T& x, const T& y) const {
        return x<y;
    }
};

(There are some other already made functors http://en.cppreference.com/w/cpp/utility/functional)

Notice that it compares two objects with <. This means that as a "general method" you only need to implement the operator bool operator< (const X& lhs, const X& rhs){...} to allow your objects to be sorted. See Operator Overloading FAQ. As a rule of thumb, if you're going to implement one comparison operator then you should implement the others too.

If you need to sort your keys in another way you can define your own comparator (functor).

template < class T >
struct myLess {
    bool operator()( const T& lhs, const T& rhs ) const {
        return lhs < rhs;
    }
};

And use it in a map like std::map< int, int, myLess<int> >.

You can also not use templates at all if you only need to compare one type.

struct myLess {
    bool operator()( const int& lhs, const int& rhs ) const {
        return lhs < rhs;
    }
};

Then you only have to write std::map< int, int, myLess >.

Keep in mind that the objects you're comparing are the Key types, not necessarily the Contained types.

Community
  • 1
  • 1
aslg
  • 1,966
  • 2
  • 15
  • 20