Suppose we have a array of std::pair
s:
using Particle = std::pair<std::string, double>;
Particle particles[] {{"Electron", 0.511}, {"Muon", 105.66}, {"Tau", 1776.86}};
We can using C++20 ranges algorithms with different projection function to sort them according to different data member:
ranges::sort(particles, {}, &Particle::first);
ranges::sort(particles, {}, &Particle::second);
This seems very clean. But when I move Particle
's data type to std::tuple
:
using Particle = std::tuple<std::string, double>;
I can't using same projection metric anymore since std::tuple
have no first
or second
member. Alternatively, just pass lambda and it's will work fine:
ranges::sort(particles, {}, [](const auto& t) { return std::get<0>(t); });
ranges::sort(particles, {}, [](const auto& t) { return std::get<1>(t); });
But is there neater project way to do that like this?
ranges::sort(particles, {}, &std::get<0>);
You can provide your own functor to do this
namespace my
{
template<size_t n>
struct get_t
{
template<typename T>
decltype(auto) operator()(T&& t) const
{
using std::get;
return get<n>(std::forward<T>(t));
}
};
template<size_t n>
inline constexpr get_t<n> get;
}
ranges::sort(particles, {}, my::get<0>);