2

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 ?

Julien BERNARD
  • 653
  • 6
  • 17

1 Answers1

3

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

Caleth
  • 52,200
  • 2
  • 44
  • 75
  • Whoops. Thanks ! – Julien BERNARD May 19 '21 at 14:37
  • 1
    Relevant quote: `The underlying array is a temporary array of type const T[N], in which each element is copy-initialized (except that narrowing conversions are invalid) from the corresponding element of the original initializer list.` – SergeyA May 19 '21 at 14:38