Capturing and editing a ValueTree in a lambda

In this code:

        ValueTree dataTree("New Files");
        
        Array<File> filesToAdd;
        
        //get a load of files to add into the array
        
        std::for_each(filesToAdd.begin(), filesToAdd.end(), [dataTree](const File& file)
        {
            ValueTree fileTree("File");
            fileTree.setProperty("Path", file.getFullPathName(), nullptr);
            dataTree.addChild(fileTree, -1, nullptr);
        });

I recieve an error on the last line of the for_each statement saying:

‘this’ argument to member function ‘addChild’ has type ‘const juce::ValueTree’, but function is not marked const

I’m not sure what this really means in the first place since this error never occurs outside of the lambda expression. Is it saying my lambda should be const? If so why?

When I change the capture of the dataTree to a reference however:

std::for_each(filesToAdd.begin(), filesToAdd.end(), [&dataTree](const File& file)

This code works fine. In most other situations I would pass a variable I wanted to edit into a lambda by reference. However, since ValueTrees are, “A lightweight reference to a shared data container.” I thought that this time I could get away by copying the variable.

Could someone please explain why I could not do this.

I believe you need the mutable keyword for your lambda…

1 Like

Yes - Thank you very much I knew I was going to have to learn about that keyword sooner or later.

Just for your interest a shorter way to write that:

ValueTree fileTree {"file", {{"Path", file.getFullPathName()}}};
dataTree.appendChild (fileTree, nullptr);

(You could even put it in one line but I didn’t want to sacrifice readability just for showing off…)

1 Like