【发布时间】:2021-08-16 21:12:28
【问题描述】:
考虑具有x、y 和z 值的Point 类型。如果我有一系列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
}
documentation 提到 std::ranges::views::elements 与“类似元组”的值一起使用。我假设它应该类似于我们如何制作我们的类型work with structured binding,但我似乎遗漏了一些东西
我已尝试使用以下代码
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(p) 来提取 x 值,但这对于 std::ranges::views::elements 来说还是不够的。要使一系列Point 对象与std::ranges::views::elements 一起工作,还需要什么?
PS:我知道我可以在这里使用views::transform,但我在这里的主要目的是通用并理解这些东西是如何组合在一起的。通用并理解这些东西是如何组合在一起的.
【问题讨论】:
-
你能提供你得到的错误信息吗?
-
另一种方法是提供一个成员函数,将
Point转换为包含对其成员godbolt.org/z/Kxnsdn1bM 的引用的tuple。
标签: c++ c++20 std-ranges