Replacing ScopedPointer with std::unique_ptr

I’m trying to make more stuff more generically C++ and use the standard library more. So, seems like a good move to replace the Juce ScopedPointer with the std library unique_ptr.

But i seem to often run into errors like this one:

Invalid operands to binary expression ('juce::TextButton *' and 'std::unique_ptr<TextButton>')

any advice?

Maybe because std::unique_ptr does not have a conversion operator to the raw pointer? You need to get the raw pointer with the .get() method.

1 Like

thank you. it was that simple :slight_smile:

We would advise everyone to move from ScopedPointers to std::unique_ptrs - we will be doing it ourselves shortly after the release of JUCE 5.3.

7 Likes

I just tested changing 2 ScopedPointer(s) to std::unique_ptr in my plug-in and I’m finding in my debug build I’m getting glitching while playing back grooves… I found this:

Have y’all tested performance between ScopedPointer and std::unique_ptr without optimizations?

Cheers,

Rail

1 Like

That sounds very odd indeed! Certainly an important part of the design of std::unique_ptr was that it’d optimise away to a raw pointer in almost all situations…

Are you sure the glitches aren’t something behaving differently because of a semantic difference?

My report was more anecdotal – I just changed the ScopedPointers and tested playback… but I was also compiling using Parallels in a VM machine at the same time… undoing and re-doing the change appeared to indicate that the glitching only occurred with the std::unique_ptr – but it may just have been coincidental… I’ll do proper testing later. I did the Google and found the linked article above, so was curious if y’all had done any testing with a Debug build.

Cheers,

Rail

No, not sure how you’d even go about benchmarking something as fundamental as that, TBH…

I am trying to replace ScopedPointer with std::unique_ptr and am getting an error that says “no operator ‘=’ matches these operands”. Here is the code:

std::unique_ptr<juce::Slider> driveKnob;
addAndMakeVisible(driveKnob = new juce::Slider("Drive"));

Does anyone have an idea of how to solve this?

Assuming you’re using at least C++14, you should use std::make_unique to allocate a new std::unique_ptr. So your above snippet becomes:

std::unique_ptr<juce::Slider> driveKnob; 
driveKnob = std::make_unique<juce::Slider> ("Drive");
addAndMakeVisible (driveKnob.get()); // use get() whenever a raw pointer is needed

Worked perfectly, thanks!

Minor stile detail: While there is nothing wrong with it, I think the overload of addAndMakeVisible that takes a reference is even better to read here, as there is a suitable operator* overload to std::unique_ptr. Therefore, I use

addAndMakeVisible (*driveKnob);

Just for the records, thanks to a backport that the JUCE team did, std::make_unique is also available if you use JUCE with C++11, it’s not necessary to have C++14 compliance for that specific feature to be available

2 Likes