unique_ptr & vector,试图访问已删除的函数,Visual Studio 2013
Posted
技术标签:
【中文标题】unique_ptr & vector,试图访问已删除的函数,Visual Studio 2013【英文标题】:unique_ptr & vector, trying to access deleted function, Visual Studio 2013 【发布时间】:2014-03-30 23:18:26 【问题描述】:我正在尝试使用 unique_ptr 来管理我的内存,而 VS2013 似乎在我认为不应该的时候给我带来了麻烦。
似乎编译器出于某种原因试图访问已删除的复制构造函数,而实际上它确实没有理由这样做。
这是我的一门课的样子:
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;
;
问题在于线路
std::vector<std::unique_ptr<Mesh>> _meshes;
它开始喷出类似的东西
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
我没有使用std::vector::resize()
或类似的东西(事实上我注释掉了我的 _meshes 向量的所有用途,甚至尝试完全注释掉实现无济于事),所以我不明白为什么编译器给我带来了问题。
有人有什么想法吗?
感谢 Preetish Kakkar 发现问题。事实证明,编译器使用 Mesh 类的复制构造函数和 operator= 隐式生成函数是一个问题,迫使编译器尝试使用已删除的函数。
【问题讨论】:
尝试为Mesh
实现移动构造函数。 AFAIK,VS2013 不会自动生成移动构造函数/移动赋值运算符。
是的,但我的理解是 std::vector 不使用移动构造函数,因此不应该出现错误。如果我正确读取错误,则它与复制构造函数有关。如果不是 std::vector<:unique_ptr>> _meshes;我做 std::unique_ptr我重现了你的问题,下面是示例代码。
#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;
问题是在某些时候您试图复制两个无法完成的模型对象,因为 unique_ptr 是不可复制的。
【讨论】:
你能粘贴编译时出错的文件代码吗?仅当您尝试复制 unique_ptr 时才会发生此错误(至少从您发布的内容来看是这样)。我确信它正在发生。 所以我在你的代码中发现了问题,Ship.hpp 就是问题所在。它使用 Model::model 很好,但由于它试图复制而导致问题。在 Model.hpp 中将复制构造函数和赋值运算符设为私有将修复它。添加模型(模型常量&); void operator=(Model const&);在模型类私有部分中 或者您可以通过从 Ship(const Ship&) = default; 中删除默认值来修复它。如果您不想让船舶可复制,那么只需将赋值和复制构造函数设为私有 - 不要为它们提供默认实现,因为默认会尝试在内部复制导致错误。 我有其他建议不包括 typedefs.hpp 中的所有内容 - 包括每个 cpp 中需要的任何内容 为什么你认为在 typedefs.hpp 中包含所有内容是不好的?当然它会减慢编译时间,但如果将来我决定使用预编译头文件,这很容易。包含我需要的所有内容的问题是,很难跟踪我真正需要的内容,并且我最终有很多“无用”的标头弄脏了我的代码。以上是关于unique_ptr & vector,试图访问已删除的函数,Visual Studio 2013的主要内容,如果未能解决你的问题,请参考以下文章
如何在 std 算法中使用 unique_ptr 的 transform_iterator