Рассмотрим тип Point
со значениями x
, y
и z
. Если у меня есть диапазон объектов Point
, например std::vector<Point>
, что мне нужно добавить к Point
, чтобы он работал с адаптером диапазона std::ranges::views::elements
?
Намерение состоит в том, чтобы сделать что-то вроде
std::vector<Point> v{...};
for (auto x : v | std::ranges::views::elements<0>) {
// do something with all `x` values
}
В документации упоминается, что std::ranges::views::elements
работает со значениями, подобными кортежам. Я предположил, что это должно работать аналогично тому, как мы можем сделать наш тип работает со структурированной привязкой, но, похоже, я что-то упускаю
Я пробовал со следующим кодом
class Point {
double x=0;
double y=0;
double z=0;
public:
Point(double x, double y, double z) : x(x), y(y), z(z) {}
template <std::size_t N>
double get() const {
if constexpr(N == 0)
return x;
else if constexpr(N == 1)
return y;
else if constexpr(N == 2)
return z;
}
};
namespace std {
template <>
struct tuple_size<Point> : std::integral_constant<std::size_t, 3> {};
template <std::size_t N>
struct tuple_element<N, Point> {
using type = double;
};
}
Этого достаточно, чтобы структурированное связывание заработало, но std::ranges::views::elements
по-прежнему не работает. Затем я подумал, что, возможно, std::ranges::views::elements
нужно std::get<n>(p)
для работы, и я добавил специализацию ниже в пространство имен std
.
template <std::size_t N>
double get(const Point &p) {
if constexpr(N == 0)
return p.get<0>();
else if constexpr(N==1)
return p.get<1>();
else if constexpr(N==2)
return p.get<2>();
}
Теперь можно использовать std::get‹0›(p) для извлечения значения x
, но опять же этого недостаточно для std::ranges::views::elements
. Что еще нужно, чтобы диапазон Point
объектов работал с std::ranges::views::elements
?
PS: Я знаю, что мог бы просто использовать здесь views::transform
, но моя главная цель здесь - быть общим и понять, как эти вещи должны сочетаться друг с другом.
Point
вtuple
, содержащую ссылки на его элементы, godbolt.org/z/ Kxnsdn1bM. - person 康桓瑋   schedule 28.05.2021