# How to combine projections with transform in C++20 ranges

C++20 `ranges::sort` supports projections, and that is great, but I want to do stuff that is more complex, in particular sort on result of function that operates on projected member.

For function call I tried the transform and then sort that view, but C++20 sort seems to not work on views, this answer explains why(for range-v3).

In other words can I write this without using a lambda/functor?

```struct S{
int val;
};

int origin = 47;

// assume we can not change Distance to take S
int Distance(int val){
return std::abs(val - origin);
}

void my_sort(std::vector<S> ss) {
std::ranges::sort(ss, std::greater<>{}, [](const S& s){
return Distance(s.val);
});
}
```

Seems like you want function composition:

```void my_sort(std::vector<S>& ss) {
std::ranges::sort(ss, std::greater<>{}, compose(Distance, &S::val));
}
```

Where `compose(f, g)(x)` does `f(g(x))`. Boost.Hof has a `compose`, there’s one in range-v3 somewhere too. Not one in the standard library though.

For function call I tried the transform and then sort that view,

There is a big difference between `sort(r, less(), f)` and `sort(r | transform(f), less())`: the former sorts `r` using the function `f` as the sort key, the latter sorts the transformed values specifically. A concrete example demonstrating the difference:

```struct X {
int i;
int j;
};

vector<X> xs = {X{1, 2}, X{2, 1}, X{0, 7}};

// this would give you (0, 7), (1, 2), (2, 1)
// because we're sorting by the i
ranges::sort(xs, less(), &X::i);

// this would have given you (0, 2), (1, 1), (2, 7)
// because we're sorting the i's independently
ranges::sort(xs | views::transform(&X::i), less());
```