尝试find_if向量中的unique_ptr时的编译错误

时间:2016-11-06 23:50:01

标签: c++ gcc unique-ptr

此代码:

#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;
}

在MSVC中正常工作,但在GCC 5.1中出错:

  

prog.cpp:在函数'int main()'中:

     

prog.cpp:19:25:错误:类型'__gnu_cxx :: __ normal_iterator *,std :: vector&gt;类型的非const引用的初始化无效&GT;&安培;”来自类型'__gnu_cxx :: __ normal_iterator *的右值,std :: vector&gt; &GT;”     汽车和放大器; it = std :: find_if(vec.begin(),vec.end(),[&amp;](std :: unique_ptr&amp; p)

  1. 哪个编译器被窃听?
  2. 如何正确删除std::vector std::unique_ptr的指针?

2 个答案:

答案 0 :(得分:5)

gcc在这里是正确的。你不能使用rvalue初始化左值引用,并且你正在对迭代器的it引用进行初始化(std::find_if返回rvalue)

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

要么使它成为一个对象:

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

demo

或const引用:

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

demo

除此之外,用于从向量中删除元素的代码是正确的

答案 1 :(得分:0)

如果您打开4级警告warning C4239: nonstandard extension used: note: A non-const reference may only be bound to an lvalue ,VS2015将发出警告,指出正在使用非标准扩展名:

#pragma warning( push, 3 )  
#include <memory>
#include <vector>
#include <algorithm>
#pragma warning( pop ) 
#pragma warning( disable : 4710 )

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;
}
1>c:\users\flatmouse\documents\visual studio 2015\projects\project79\project79\source.cpp(25): warning C4239: nonstandard extension used: 'initializing': conversion from 'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::unique_ptr<Foo,std::default_delete<_Ty>>>>>' to 'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::unique_ptr<Foo,std::default_delete<_Ty>>>>> &'
1>          with
1>          [
1>              _Ty=Foo
1>          ]
1>  c:\users\flatmouse\documents\visual studio 2015\projects\project79\project79\source.cpp(25): note: A non-const reference may only be bound to an lvalue

产地:

{{1}}