Range-based for loop over ValueTree does not compile

#1

It is extremely surprising to me that this does not compile:

juce::ValueTree tree;
for (auto& child : tree) { /* code */ }
#2

Isn’t that due to the reference type? I don’t see anything that allows getting ValueTree children by reference even outside of iterators

#3

yep, looks like ValueTree::Iterator isn’t really a LegacyForwardIterator because its operator* returns by value instead of by reference.

https://en.cppreference.com/w/cpp/named_req/ForwardIterator

1 Like
#4

I suppose the iterator could be tweaked to have a private member which is the Value, and then return a reference to it rather than just creating a Value and returning it when needed, but somehow it seems icky to be returning a reference to an object that’s contained in the iterator itself…

#5

Looks like vector<bool> also doesn’t provide iterators implementing LegacyForwardIterator, so this wouldn’t work either:

std::vector<bool> vec;
for (auto& i : vec) { /* code */ }

Perhaps one solution is just to iterate using auto&& instead.

#6

const auto& would probably also work

1 Like
#7

Not if you want to modify the children.

Yes, it’s exactly the same problem as with vector<bool>: the iterator does not return references to objects that exist inside the tree. Therefore, ValueTree is not a container, and range-based for loops and STL algorithms don’t work.