How to use remove_if on an std::vector of std::unique_ptr?

Viewed 119

I'm trying to remove_if a vector of unique_ptr. Having forgotten to have my lambda not attempt to copy parameters, I searched for the explanation and found it in Can you use `std::remove_if` on a container of `std::unique_ptr`?.

But when I attempt to pass my lambda parameter by reference or const ref as advised there and in other questions on the matter, I still get 'std::unique_ptr<int,std::default_delete<int>>::unique_ptr(const std::unique_ptr<int,std::default_delete<int>> &)': attempting to reference a deleted function. I don't get why this copy construct would be called.

std::vector<std::unique_ptr<int>> v {
    std::make_unique<int>(1),
    std::make_unique<int>(2),
    std::make_unique<int>(3)
};

auto result = std::remove_if(v.begin(), v.end(), [](const std::unique_ptr<int> &it) {return *it > 2; });

What am I missing ?

1 Answers

What am I missing ?

It's complaining about the construction, not the use.

std::initialiser_list can only be copied from, so std::initialiser_list<std::unique_ptr<...>> is useless.

#include <memory>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<std::unique_ptr<int>> v;
    v.emplace_back(std::make_unique<int>(1));    
    v.emplace_back(std::make_unique<int>(2));    
    v.emplace_back(std::make_unique<int>(3));    
    
    auto result = std::remove_if(v.begin(), v.end(), [](const std::unique_ptr<int> &it) {return *it > 2; });
    v.erase(result, v.end());
}

See it on coliru

Related