#include <algorithm>
#include <iostream>
#include <vector>
using namespace std; // Bad practice, but just to keep things readable.
// Generic sort with comparator.
template <typename F, typename T>
T sortBy(F cmp, T xs) {
sort(xs.begin(), xs.end(), cmp);
return xs;
};
// Sort with implicit comparator. We name it with an underscore to avoid confusion with std::sort.
#define sort_(xs) sortBy(cmp, xs) // `cmp` is "implicit".
// Helper function.
void print(const vector<pair<int, int>>& xs) {
for (const auto& [a, b] : xs)
cout << " (" << a << ", " << b << ")";
cout << "\n";
};
int main() {
auto xs = vector<pair<int, int>>{ {1, 42}, {5, 8}, {10, 4}, {3, 14}, {15, 92} };
{ // (1, 42) (3, 14) (5, 8) (10, 4) (15, 92)
auto cmp = [](auto pa, auto pb) { return pa.first < pb.first; };
print(sortBy(cmp, xs));
print(sort_(xs)); // Expanded to `print(sortBy(cmp, xs));`.
}
{ // (15, 92) (1, 42) (3, 14) (5, 8) (10, 4)
auto cmp = [](auto pa, auto pb) { return pa.second > pb.second; };
print(sort_(xs)); // Same expansion happens here.
}
}