---
id: custom-cpp-stl
title: "C++ STL with Custom Comparators"
author: Siyong Huang, Benjamin Qi
prerequisites:
- Silver - Sorting with Custom Comparators
- Silver - Introduction to Ordered Sets
description: "?"
frequency: 1
---
Covers all of this material.
What if we want to use a C++ `set` with the `Edge` struct that was defined in the previous module?
## Operator Overloading
Works as expected, although you should make sure to include the second `const` or you'll get a compilation error.
```cpp
#include
using namespace std;
struct Edge {
int a,b,w;
bool operator<(const Edge& y) const { return w < y.w; }
};
int main() {
int M = 4;
set v;
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.insert({a,b,w});
}
for (Edge e: v) cout << e.a << " " << e.b << " " << e.w << "\n";
}
```
## Comparator
```cpp
#include
using namespace std;
struct Edge {
int a,b,w;
};
bool cmp(const Edge& x, const Edge& y) { return x.w < y.w; }
int main() {
int M = 4;
set v(cmp);
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.insert({a,b,w});
}
for (Edge e: v) cout << e.a << " " << e.b << " " << e.w << "\n";
}
```
Lambda expressions also work:
```cpp
auto cmp = [](const Edge& x, const Edge& y) { return x.w < y.w; };
int main() {
int M = 4;
set v(cmp);
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.insert({a,b,w});
}
for (Edge e: v) cout << e.a << " " << e.b << " " << e.w << "\n";
}
```
In this case, we can shorten the declaration of `v` by writing `set v(cmp);` instead.
## Functors
Probably less confusing than the method above.
```cpp
#include
using namespace std;
struct Edge {
int a,b,w;
};
struct cmp {
bool operator()(const Edge& x, const Edge& y) { return x.w < y.w; }
};
int main() {
int M = 4;
set v;
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.insert({a,b,w});
}
for (Edge e: v) cout << e.a << " " << e.b << " " << e.w << "\n";
}
```
We can also use `cmp` like a normal function by adding `()` after it.
```cpp
int main() {
int M = 4;
vector v;
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.push_back({a,b,w});
}
sort(begin(v),end(v),cmp());
for (Edge e: v) cout << e.a << " " << e.b << " " << e.w << "\n";
}
```
## Built-In Functors
Overloading `<` automatically generates the functor `less`. Similarly, overloading `>` automatically generates the functor [`greater`](https://en.cppreference.com/w/cpp/utility/functional/greater). We can use this to store a set in reverse order.
```cpp
#include
using namespace std;
struct Edge {
int a,b,w;
bool operator>(const Edge& y) const { return w > y.w; }
};
int main() {
int M = 4;
set> v;
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.insert({a,b,w});
}
for (Edge e: v) cout << e.a << " " << e.b << " " << e.w << "\n";
}
/* Output:
2 3 10
1 2 9
1 3 7
2 4 3
*/
```
## Other Containers
The following are all valid:
```cpp
set> a;
map> b;
priority_queue,greater> c;
```