0

How to join range of ranges?

auto points() const
    {
        auto ranges = children() | std::views::transform([](auto child) { return child->points(); });
        return std::views::join(ranges);
    }

Can`t use points at

for(auto& pt: points())

Error no operator "!=" matches these operands

Jevs
  • 25
  • 5

1 Answers1

1

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&.

Fureeish
  • 12,533
  • 4
  • 32
  • 62