2016-11-06 6 views
3

Dieser Code zu find_if versuchen:Übersetzungsfehler, wenn ein unique_ptr in einem Vektor

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

funktioniert in MSVC, aber Fehler aus 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. Welche Compiler abgehört wird? Wie kann ich einen Zeiger von std::vector von std::unique_ptr korrekt löschen?
+0

"abgehört" impliziert ein unbeabsichtigtes Verhalten. Es ist nicht. Die MSVC-Entwickler sind sich dessen bewusst und haben nicht die Absicht, sie jemals zu ändern. –

+1

Wenn Sie jedoch die Einhaltung strenger Standards erzwingen möchten (nach bestem Wissen des Compilers), verwenden Sie das ['/ Za'-Flag] (https://msdn.microsoft.com/de-de/library/0k0w269d. aspx). –

Antwort

4

gcc ist hier korrekt. Sie können kein L-Wert-Referenz mit einem R-Wert initialisieren, und Sie tun es für die it Verweis auf ein Iterator (std::find_if kehrt ein R-Wert)

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

Entweder machen es zu einem Objekt:

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

demo

oder ein const Referenz:

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

demo

Other than that, Ihr Code ein Element aus einem Vektor zum Löschen ist richtig

0

VS2015 eine Warnung aus, dass eine Nicht-Standard-Erweiterung verwendet wird, wenn Sie auf der Ebene 4 Warnungen drehen /W4:

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

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

Produziert:

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 
Verwandte Themen