I was working with STL containers, trying to implement custom comparators/predicates, and I realized when giving the predicate as a Functor there seem to be same syntax for all containers, i.e. you just mention the name of the Functor as the respective argument in the template arguments, and bam it works!

Now coming to Lambdas they work fine in containers like in `std::vector`, but not in `std::set` the syntax is really weird. Here is some code related to that

For `std::vector` this works fine

```
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> a = { 3, 1, 0, 2 };
    sort(a.begin(), a.end(), [](const int& num1, const int& num2) -> bool {
        return num1 < num2;
    });

    for (const int& num : a)
    {
        cout << num << " ";
    }
}

```

But for `std::set` this doesn't work

```
auto PredicateLambda = [](const pair<int, string>& p1, const pair<int, string>& p2) -> bool {
    if (p1.first != p2.first)
        return p1.first < p2.first;
    else
        return p1.second < p2.second;
};

set<pair<int, string>, PredicateLambda> st;

```

rather, you will have to do

```
set<pair<int, string>, decltype(PredicateLambda)> st(PredicateLambda);

```

I find this really weird considering that type is anyway determined during compile time and manually specifying seems unnecessary. I feel like I'm missing something here, really appreciate if someone can fill the gap on why it is done like this?

P.S. One explanation I had in mind is there is some kind of static-time checking of the type of the predicate but, this brings another question to mind how is type checking done in case of Functors which seems to works fine normally(i.e. just specifying the name of the functor)

---

**Edit**: The intention of the question is not about getting to know the syntax, but rather the reasoning behind the design. The reason is that `std::sort()` essentially needs just a callable object which can compare two values and uses that to sort in-place, whereas `std::set` class has to declare the predicate in its class and hence would also need the type of the object too. When we give Functor's name, we are essentially giving the Class Name(which is like a type) but `PredicateLambda` is an object and hence we use `decltype` to figure its type.