Pie-Lie-Die's blog

By Pie-Lie-Die, history, 4 years ago, In English

Can anyone explain how to use custom comparators or provide a link?

What confuses me the most is that for some comparator we write the comparator as a struct/class and overload the < operator while sometimes we just write a comparator that takes two instances returns true if first should be before second in ordering.

I'll write the following snippets. Is there any difference in those two? It is just a preference? Or both are just different ways to write? If so, which is better? Also, we can just use lambda function to do this, which is much easier but I really wanted to know how traditional comparators worked.

bool comp(int& a, int& b)
{
    return freq[a] < freq[b]; // Freq is a global array.
}

To sort using above comparator we write,

vector arr = {0,5,6,1}; sort(arr.begin(), arr.end(), comp);

class comparator{
     bool operator()(int& a, int& b)
     {
         return freq[a] < freq[b] ; 
     }
};

To sort using this, we write the following,

vector arr = {0,5,6,1}; sort(arr.begin(),arr.end(),comparator);

auto comp = [](int& a, int& b){ return freq[a] < freq[b] };

To sort using lambda, we write the following,

vector arr = {0,5,6,1}; sort(arr.begin(),arr.end(),comp);

Please tell me when to use what, and what the differences are. I really don't seem to understand this.

  • Vote: I like it
  • +8
  • Vote: I do not like it

| Write comment?
»
4 years ago, # |
  Vote: I like it 0 Vote: I do not like it

According to my knowledge, your function comparators named as comp and lambda function comp are used with the function like sort(A.begin(), A.end(), comp), but the class-based comparator which overloads the operator() can even do more. Suppose if you want to keep your std::set in a particular order, then you need a custom comparator, now at this point, we need operator(), which will be called whenever insertion or deletion takes place.

You already knew how to use a function comparator which is only used with the functions.

To use class comparator (operator()), we have to pass that comparator into the STL object.

code

You can also view my submission based on this comparator.

Suggestions are welcome.

  • »
    »
    4 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    If we are to use a comparator inside a class, do we declare function inside class or outside class? Also, normal function comparator doesn't work with priority queue. It specifically needs class comparator. Can you explain why?

    • »
      »
      »
      4 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      priority queue need additional argument as vector<T> code: link

      For more information, Do some experiments

»
4 years ago, # |
  Vote: I like it 0 Vote: I do not like it

You need a class template only for set, map, priority_queue, multiset and multimap. All other STL containers works with a comparator function or lambda function. And as for comparator with class template you have to overload the () operator in the following way:

struct comparator_name
{
	bool operator()(const class_name &B,const class_name &A) const
	{
		//Your code..
	}
};

Here class name is the name of the class which is in the container(set, map, etc). the const keyword is essential as any call to non-const member functions by the container is prohibited.

»
4 years ago, # |
Rev. 3   Vote: I like it 0 Vote: I do not like it

Someone please help with comparators?

Any link which lists all the syntax and use cases