We want to implement a tree of items:
+----------------------+
| Item (interface) |
+----------------------+
| + getName(): string |-----------+
+----------------------+ |
^ |
| |
+------+------+ |
| | |
+-------------+ +------------+ |
| SimpleItem | | Group |<>--+
+-------------+ +------------+
| +add(Item) |
| +all() |
+------------+
The Group::all() function shall return a flattened recursive view of all items including self, as pairs of: {recursion level, item}.
An implementation using ranges::views fails, as the return type of all, depends on the level (a view of a view of items is not the same type as a view of items).
So this code doesn't compile:
auto all(size_t level = 0) const {
return views::concat(
views::single(std::pair<size_t, std::shared_ptr<const Item>>(level, shared_from_this())),
views::join(items |
views::transform([level](const auto& item) {
auto group = std::dynamic_pointer_cast<Group>(item);
if (group == nullptr) {
return views::single(std::pair{level + 1, item});
}
else {
return group->all(level + 1);
}
})
)
);
}
Code: https://compiler-explorer.com/z/fdc8rsWae
Any idea how to make the all function work and return the desired flattened view of all recursive items?
* Note: the code uses ranges-v3, as we use concat, which is added to std::ranges only in C++26. Solutions may rely either on std::ranges or on ranges-v3.
Group? (I know I could look at your source code.) I mean, what prevents you from going to the basics and simply iterating this collection recursively? The second question is: how does the object graph of all theIteminstances look? It does not have to be a tree. In the case of the general graph, you will have to avoid infinite loops. To do so, you can, for example, create a temporary hash set of the already visitedItemnodes. Basically, that's all. Any problem with this?std::shared_ptr<const Item>in your view and notItem&? You're going to build up a view so why pay for the ownership overhead of shared_ptr?allshould be a virtual function inItem. Alternatively, use astd::variantinstead of an hierarchy.