C++ 尝试查找向量中唯一的\u ptr时出现编译错误

C++ 尝试查找向量中唯一的\u ptr时出现编译错误,c++,gcc,unique-ptr,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_

此代码:

#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;
}
#包括
#包括
#包括
结构Foo
{
int-bar;
Foo(const int val):
巴(瓦尔)
{
}
};
int main(){
std::vec;
vec.emplace_back(标准::使_独一无二(42));
Foo*ptr=vec.back().get();
auto&it=std::find_if(vec.begin()、vec.end()、[&](std::unique_ptr&p)
{
返回p.get()==ptr;
});
如果(it!=vec.end())
{
删除(它);
}
返回0;
}
在MSVC中工作正常,但在GCC 5.1中出现错误:

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

prog.cpp:19:25:错误:类型为“\uu gnu\u cxx::\uu normal\u iterator*,std::vector>>”和“来自类型为“\uu gnu\u cxx::\uu normal\u iterator*,std::vector>>”的右值的非常量引用初始化无效 auto&it=std::find_if(vec.begin()、vec.end()、[&](std::unique_ptr&p)

  • 哪个编译器被窃听了
  • 如何正确地从
    std::unique\u ptr
    std::vector
    中删除指针

  • gcc在这里是正确的。您不能用右值初始化左值引用,您是为对迭代器的
    it
    引用(返回右值)进行初始化的

    auto&it=std::find_if(vec.begin(),vec.end(),[&](std::unique_ptr&p)
    ^
    
    或者将其作为对象:

    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&p)
    

    或常量引用:

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


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

    VS2015将发出一条警告,如果您启用级别4警告,则会使用非标准扩展:

    warning C4239: nonstandard extension used:
    note: A non-const reference may only be bound to an lvalue
    

    #pragma警告(推送,3)
    #包括
    #包括
    #包括
    #布拉格警告(pop)
    #杂注警告(禁用:4710)
    结构Foo
    {
    int-bar;
    Foo(const int val):
    巴(瓦尔)
    {
    }
    };
    int main(){
    std::vec;
    vec.emplace_back(标准::使_独一无二(42));
    Foo*ptr=vec.back().get();
    auto&it=std::find_if(vec.begin()、vec.end()、[&](std::unique_ptr&p)
    {
    返回p.get()==ptr;
    });
    如果(it!=vec.end())
    {
    删除(它);
    }
    返回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>c:\users\flatmouse\documents\visualstudio 2015\projects\project79\project79\source.cpp(25):警告C4239:使用了非标准扩展:“初始化”:从“std::\u Vector\u iterator”转换为“std:\u Vector\u iterator&”
    1> 与
    1>          [
    1> _Ty=Foo
    1>          ]
    1> c:\users\flatmouse\documents\visual studio 2015\projects\project79\project79\source.cpp(25):注意:非常量引用只能绑定到左值
    
    “bugged”意味着这是无意的行为。事实并非如此。MSVC开发人员非常清楚这一点,也无意对其进行任何更改。但是,如果您想强制严格遵守标准(尽编译器当前的最大能力),请使用。
    #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