Everything depends on what exactly children()
and child::points()
return.
If children()
returns a container by value, then you are creating an adaptor (via piping with |
) that is dangling - its iterators cannot be dereferenced.
In addition, child::points()
must return a view
. Returning a container won't work.
Here is a working example:
#include <iostream>
#include <vector>
#include <ranges>
struct child {
std::vector<int> points_{1, 2, 3};
const auto& points() const {
return points_;
}
};
struct element {
std::vector<child> children_{{}, {}};
const auto& children() const {
return children_;
}
auto points() const {
auto ranges = children() | std::views::transform([](auto& child) {
return std::views::all(child.points());
});
return std::views::join(ranges);
}
};
int main() {
auto e = element();
for (auto x : e.points()) {
std::cout << x << ' ';
}
}
Notice how accessors (child::points()
and element::children()
) return by const&
.