Как спроецировать std :: tuple в c 20 ограниченных алгоритмов

#c #c 20 #range-v3

#c #c 20 #диапазон -v3

Вопрос:

Предположим, у нас есть массив std::pair s:

 using Particle = std::pair<std::string, double>;
Particle particles[] {{"Electron", 0.511}, {"Muon", 105.66}, {"Tau", 1776.86}};
  

Мы можем использовать C 20 алгоритмов диапазонов с разной функцией проецирования, чтобы сортировать их по разным элементам данных:

 ranges::sort(particles, {}, amp;Particle::first);
ranges::sort(particles, {}, amp;Particle::second);
  

Это кажется очень чистым. Но когда я перемещаю Particle тип данных в std::tuple :

 using Particle = std::tuple<std::string, double>;
  

Я больше не могу использовать ту же метрику проекции, поскольку std::tuple у меня нет first second члена or. В качестве альтернативы, просто передайте lambda, и он будет работать нормально:

 ranges::sort(particles, {}, [](const autoamp; t) { return std::get<0>(t); });
ranges::sort(particles, {}, [](const autoamp; t) { return std::get<1>(t); });
 
  

Но есть ли более аккуратный проектный способ сделать это подобным образом?

 ranges::sort(particles, {}, amp;std::get<0>); 
  

Комментарии:

1. Вы можете использовать из std::tie

2. Могу я спросить, почему вы движетесь к кортежу? Мне просто интересно, могли бы мы сделать еще лучше с небольшим struct (с полезными именами в полях)

Ответ №1:

Для этого вы можете предоставить свой собственный функтор

 namespace my
{
    template<size_t n>
    struct get_t
    {
        template<typename T>
        decltype(auto) operator()(Tamp;amp; 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>);