Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compilation error when trying to find_if an unique_ptr in a vector

This code:

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

struct Foo
{
    int bar;

    Foo(const int val) :
        bar(val)
    {
    }
};

int main() {
    std::vector<std::unique_ptr<Foo>> vec;
    vec.emplace_back(std::make_unique<Foo>(42));
    Foo* ptr = vec.back().get();
    auto& it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr<Foo>& p)
    {
        return p.get() == ptr;
    });
    if (it != vec.end())
    {
        vec.erase(it);
    }

    return 0;
}

Works fine in MSVC, but errors out in GCC 5.1:

prog.cpp: In function 'int main()':

prog.cpp:19:25: error: invalid initialization of non-const reference of type '__gnu_cxx::__normal_iterator*, std::vector > >&' from an rvalue of type '__gnu_cxx::__normal_iterator*, std::vector > >' auto& it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr& p)

  1. Which compiler is bugged?
  2. How do I erase a pointer from a std::vector of std::unique_ptr correctly?
like image 904
Ivan Rubinson Avatar asked Mar 11 '23 17:03

Ivan Rubinson


1 Answers

gcc is correct here. You can't initialize a lvalue reference with an rvalue, and you're doing it for the it reference to an iterator (std::find_if returns an rvalue)

auto& it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr<Foo>& p)
    ^

Either make it an object:

auto it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr<Foo>& p)

demo

or a const reference:

auto const& it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr<Foo>& p)

demo

Other than that, your code for erasing an element from a vector is correct

like image 115
krzaq Avatar answered Apr 29 '23 16:04

krzaq