#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>);