0

I am trying to keep the elements of a set<pair<ll,pair<ll,ll> > > st in descending order according to the following logic:

bool comp(pair<ll,pair<ll,ll> > a, pair<ll,pair<ll,ll> > b){
    if(a.first!=b.first)
        return a.first > b.first;
    return a.second.first > b.second.first;
}

On declaring the set using : set<pair<ll,pair<ll,ll> > , comp> st;

It gives the following error:

error: template argument for template type parameter must be a type

Usually when sorting a vector we do : sort(v.begin(),v.end(),comp) assuming that v is a vector of pair<ll,pair<ll,ll> >

How do the two cases differ and how should the I correctly execute the logic?

asn
  • 2,408
  • 5
  • 23
  • 37
  • Difference between `std::set` and `std::sort` is that the latter uses template argument deduction btw. Do you need a dupe for that too? – Baum mit Augen Feb 23 '19 at 11:46
  • I was actually trying to make `comp` function analogous in both the situations since their role was kind of same. – asn Feb 23 '19 at 11:53
  • 1
    Well, "kind of" indeed. For `std::set`, you need a template type argument, and for `std::sort`, you need a function argument, i.e. a value, not a type. – Baum mit Augen Feb 23 '19 at 11:56
  • Aah !! I got it. – asn Feb 23 '19 at 11:57

1 Answers1

0

Instead of defining a comp function, define a struct comp with operator() with the same logic as your function, but keep in mind that is has to be a const operator.

struct comp{
    bool operator () (pair<ll,pair<ll,ll> > a, pair<ll,pair<ll,ll> > b) const {
        if(a.first!=b.first)
            return a.first > b.first;
        return a.second.first > b.second.first;
    }
}
Fureeish
  • 12,533
  • 4
  • 32
  • 62
  • Can you help in explaining how is it different from the `comp` function and delve a little deeper in how does your solution works? Also, Why did you add const ? Does it matter to include/exclude it? – asn Feb 23 '19 at 12:17
  • How can I change that in the form of a template? – asn Feb 23 '19 at 12:21
  • My solution works, while your does not, because that's how `std::set` was designed. It just has to be a type, treated like a functor (overloaded `operator()`) that returns a `bool`. It also has to be `const`, because that's how the usage of it inside `std::set` uses it. Can you elaborate on "How can I change that in the form of a template?"? – Fureeish Feb 23 '19 at 13:19
  • Template function rather than in the form of `functor`? Also, I learned that const is used to ensure that the member variables of a class are unaltered. But, here we don't have any data member. – asn Feb 23 '19 at 14:43
  • You can't do that with a function template. It has to be a type and `std::set` has to create a functor (object) of that type. It's just how it is. You could make `comp` a class template though. The fact that we have no fields does not matter. Comparators should be `const`. Rarely it will work without it, if at all. – Fureeish Feb 23 '19 at 14:52