2014-03-30 6 views
21

Ich versuche unique_ptr zu verwenden, um mein Gedächtnis zu verwalten, und VS2013 scheint mir Ärger zu geben, wenn ich denke, dass es nicht sein sollte.unique_ptr & vector, versucht auf gelöschte Funktion zuzugreifen, Visual Studio 2013

Es scheint, dass der Compiler aus irgendeinem Grund versucht, auf einen gelöschten Kopierkonstruktor zuzugreifen, wenn er eigentlich keinen Grund dafür haben sollte. Diese

ist, was einer meiner Klassen wie folgt aussieht:

class Mesh 
{ 
public: 
    Mesh(oglplus::Program* program, const std::vector<Vertex>& vertices, 
        const std::vector<GLuint>& indices); 
    void draw(); 
private: 
    const oglplus::Program* _program; 
    std::vector<Vertex> _vertices; 
    std::vector<GLuint> _indices; 
    oglplus::Buffer _faceBuffer; 
    oglplus::Buffer _vertexBuffer; 
    oglplus::VertexArray _vao; 
}; 

class Model 
{ 
public: 
    Model(std::string filename, oglplus::Program* program); 
    void draw(); 
private: 
    const oglplus::Program* _program; 
    std::vector<std::unique_ptr<Mesh>> _meshes; 
}; 

Das Problem mit der Linie ist

std::vector<std::unique_ptr<Mesh>> _meshes; 

es beginnt Dinge wie

2>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(593): error C2280: 'std::unique_ptr<Model::Mesh,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function 
2>   with 
2>   [ 
2>    _Ty=Model::Mesh 
2>   ] 
2>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\memory(1486) : see declaration of 'std::unique_ptr<Model::Mesh,std::default_delete<_Ty>>::unique_ptr' 
2>   with 
2>   [ 
2>    _Ty=Model::Mesh 
2>   ] 
2>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(592) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)' 
2>   with 
2>   [ 
2>    _Ty=std::unique_ptr<Model::Mesh,std::default_delete<Model::Mesh>> 
2>   ] 
2>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(723) : see reference to function template instantiation 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)' being compiled 
2>   with 
2>   [ 
2>    _Ty=std::unique_ptr<Model::Mesh,std::default_delete<Model::Mesh>> 
2>   ] 
2>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\type_traits(572) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled 
2>   with 
2>   [ 
2>    _Ty=std::unique_ptr<Model::Mesh,std::default_delete<Model::Mesh>> 
2>   ] 
2>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector(650) : see reference to class template instantiation 'std::is_empty<_Alloc>' being compiled 
2>   with 
2>   [ 
2>    _Alloc=std::allocator<std::unique_ptr<Model::Mesh,std::default_delete<Model::Mesh>>> 
2>   ] 
2>   c:\users\vitali\projects\3d-stg\source\model\model.hpp(45) : see reference to class template instantiation 'std::vector<std::unique_ptr<Model::Mesh,std::default_delete<_Ty>>,std::allocator<std::unique_ptr<_Ty,std::default_delete<_Ty>>>>' being compiled 
2>   with 
2>   [ 
2>    _Ty=Model::Mesh 
2>   ] 
2> model.cpp 

spuckt ich nicht mit std::vector::resize() oder etwas ähnliches (in der Tat habe ich alle Verwendungen meines _Meshes-Vektors auskommentiert und sogar versucht, c die Umsetzung völlig vergeblich zu überdenken), so dass ich nicht verstehe, warum der Compiler mir Probleme gibt.

Hat jemand irgendwelche Ideen?


Vielen Dank Preetish Kakkar für das Finden des Problems. Es stellte sich heraus, dass es ein Problem mit Compiler-generierten Funktionen war, die implizit den Kopierkonstruktor und operator = der Mesh-Klasse verwendeten, was den Compiler dazu zwang, gelöschte Funktionen zu verwenden.

+2

Versuchen Sie, einen Verschiebungskonstruktor für 'Mesh' zu implementieren. AFAIK, VS2013 generiert Bewegungskonstruktoren/Bewegungszuweisungsoperatoren nicht automatisch. – Praetorian

+1

Richtig, aber es ist mein Verständnis, dass std :: vector nicht Move-Konstruktoren verwendet, und daher sollten keine Fehler vorhanden sein. Wenn ich den Fehler richtig lese, hat das etwas mit Kopierkonstruktoren zu tun. Auch wenn statt std :: vector > _meshes; Ich tue std :: unique_ptr _mesh, alles kompiliert gut. Auch wenn ich nur reguläre Zeiger std :: vector _meshes verwende, kompiliert alles auch gut. – Vitali

+0

Verwenden Sie den '-std = C++ 11' Modus? – Shoe

Antwort

16

Ich reproduzierte Ihr Problem, unten ist Beispielcode.

#include <vector> 
#include <memory> 

class Mesh 
{ 
public: 
    Mesh() {} 
    void draw() {} 
private: 
}; 

class Model 
{ 
public: 
    Model() {} 
    void draw() {} 
private: 
    typedef std::unique_ptr<Mesh> MeshUniquePtr; 
    std::vector<MeshUniquePtr> _meshes; 
}; 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    Model m; 
    Model m1; 
    m = m1; // causes error as you can't copy unique ptr 

    return 0; 
} 

Das Problem ist, an einem gewissen Punkt, den Sie versuchen, zwei Modellobjekt zu kopieren, die getan werden kann, nicht als unique_ptr nicht kopierbar ist.

+0

Kannst du den Code der Datei einfügen, der Fehler beim Kompilieren gibt. Dieser Fehler kann nur auftreten, wenn Sie versuchen, das unique_ptr zu kopieren (zumindest von dem, was Sie gepostet haben). Ich bin mir sicher, dass es passiert. – Blackhole

+1

So habe ich das Problem in Ihrem Code gefunden, Ship.hpp ist, wo das Problem herkommt. Es verwendet Model :: model, das ist in Ordnung, verursacht aber ein Problem, weil es versucht zu kopieren. Wenn Sie den Kopierkonstruktor und den Zuweisungsoperator in Model.hpp privat machen, wird das Problem behoben.füge Modell hinzu (Model const &); void operator = (Modell const &); in der Modellklasse privater Abschnitt – Blackhole

+2

Oder Sie können es beheben, indem Sie den Standard von Ship entfernen (const Ship &) = default; Wenn Sie wollen, dass Schiff nicht kopierbar sein soll, dann machen Sie einfach den Zuweisungs- und Kopierkonstruktor privat - Geben Sie ihnen nicht die Standardimplementierung als Standard, versuchen Sie intern, Fehler zu verursachen. – Blackhole