std::unique_ptr<Mesh>::unique_ptr(__gnu_cxx::__alloc_traits<std::allocator<Mesh> >

Posted

技术标签:

【中文标题】std::unique_ptr<Mesh>::unique_ptr(__gnu_cxx::__alloc_traits<std::allocator<Mesh> >::value_type&)’【英文标题】: 【发布时间】:2016-07-04 15:36:35 【问题描述】:

我正在使用 C++ std11,并且我有以下代码

#include "RenderEngine.h"
#include "Cam.h"
#include "Vec3d.h"
#include "Mesh.h"
#include "Model.h"
#include <vector>
#include <memory>

struct Option

  int imageWidth, imageHeight;
;

int main()

Cam* cam = new Cam(Vec3d(0.0, 0.0, 250.0), Vec3d(0.0, 0.0, -1.0), 90, 1);
//Cam* cam = new Cam();
Option option;
option.imageWidth = 1920;
option.imageHeight = 1080;

//option.imageWidth = 1280;
//option.imageHeight = 900;
Model myModel;
myModel.loadModel("/models/arm.obj");
std::vector<std::unique_ptr<Mesh>> objects;
std::unique_ptr<Mesh> myMesh( myModel.meshes[0] );
objects.push_back(std::move(myMesh));

RenderEngine* render = new RenderEngine(*cam, option.imageWidth, option.imageHeight);

render->getImage(objects);

delete cam;
delete render;

return 0;

我的班级Model 包含std::vector&lt;Mesh&gt; meshes

当我编译这段代码时出现以下错误:

    andreaolivieri@andreaolivieri-Aspire-V3-571:~/Documenti/C++/Progetti_POG/002_Beta$ make
g++ -Wall -c -g -std=c++11  testRender.cpp -o obj/testRender.o -Llib
testRender.cpp: In function ‘int main()’:
testRender.cpp:27:50: error: no matching function for call to ‘
  std::unique_ptr<Mesh> myMesh( myModel.meshes[0] );
                                                  ^
testRender.cpp:27:50: note: candidates are:
In file included from /usr/include/c++/4.8/memory:81:0,
                 from RenderEngine.h:13,
                 from testRender.cpp:1:
/usr/include/c++/4.8/bits/unique_ptr.h:176:2: note: template<class _Up, class> std::unique_ptr<_Tp, _Dp>::unique_ptr(std::auto_ptr<_Up>&&)
  unique_ptr(auto_ptr<_Up>&& __u) noexcept;
  ^
/usr/include/c++/4.8/bits/unique_ptr.h:176:2: note:   template argument deduction/substitution failed:
testRender.cpp:27:50: note:   ‘__gnu_cxx::__alloc_traits<std::allocator<Mesh> >::value_type aka Mesh’ is not derived from ‘std::auto_ptr<_Up>’
  std::unique_ptr<Mesh> myMesh( myModel.meshes[0] );
                                                  ^
In file included from /usr/include/c++/4.8/memory:81:0,
                 from RenderEngine.h:13,
                 from testRender.cpp:1:
/usr/include/c++/4.8/bits/unique_ptr.h:169:2: note: template<class _Up, class _Ep, class> std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Up, _Ep>&&)
  unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
  ^
/usr/include/c++/4.8/bits/unique_ptr.h:169:2: note:   template argument deduction/substitution failed:
testRender.cpp:27:50: note:   ‘__gnu_cxx::__alloc_traits<std::allocator<Mesh> >::value_type aka Mesh’ is not derived from ‘std::unique_ptr<_Tp, _Dp>’
  std::unique_ptr<Mesh> myMesh( myModel.meshes[0] );
                                                  ^
In file included from /usr/include/c++/4.8/memory:81:0,
                 from RenderEngine.h:13,
                 from testRender.cpp:1:
/usr/include/c++/4.8/bits/unique_ptr.h:160:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>&&) [with _Tp = Mesh; _Dp = std::default_delete<Mesh>]
       unique_ptr(unique_ptr&& __u) noexcept
       ^
/usr/include/c++/4.8/bits/unique_ptr.h:160:7: note:   no known conversion for argument 1 from ‘__gnu_cxx::__alloc_traits<std::allocator<Mesh> >::value_type aka Mesh’ to ‘std::unique_ptr<Mesh>&&’
/usr/include/c++/4.8/bits/unique_ptr.h:157:17: note: constexpr std::unique_ptr<_Tp, _Dp>::unique_ptr(std::nullptr_t) [with _Tp = Mesh; _Dp = std::default_delete<Mesh>; std::nullptr_t = std::nullptr_t]
       constexpr unique_ptr(nullptr_t) noexcept : unique_ptr()  
                 ^
/usr/include/c++/4.8/bits/unique_ptr.h:157:17: note:   no known conversion for argument 1 from ‘__gnu_cxx::__alloc_traits<std::allocator<Mesh> >::value_type aka Mesh’ to ‘std::nullptr_t’
/usr/include/c++/4.8/bits/unique_ptr.h:151:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer, typename std::remove_reference<_To>::type&&) [with _Tp = Mesh; _Dp = std::default_delete<Mesh>; std::unique_ptr<_Tp, _Dp>::pointer = Mesh*; typename std::remove_reference<_To>::type = std::default_delete<Mesh>]
       unique_ptr(pointer __p,
       ^
/usr/include/c++/4.8/bits/unique_ptr.h:151:7: note:   candidate expects 2 arguments, 1 provided
/usr/include/c++/4.8/bits/unique_ptr.h:146:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer, typename std::conditional<std::is_reference<_Dp>::value, _Dp, const _Dp&>::type) [with _Tp = Mesh; _Dp = std::default_delete<Mesh>; std::unique_ptr<_Tp, _Dp>::pointer = Mesh*; typename std::conditional<std::is_reference<_Dp>::value, _Dp, const _Dp&>::type = const std::default_delete<Mesh>&]
       unique_ptr(pointer __p,
       ^
/usr/include/c++/4.8/bits/unique_ptr.h:146:7: note:   candidate expects 2 arguments, 1 provided
/usr/include/c++/4.8/bits/unique_ptr.h:141:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer) [with _Tp = Mesh; _Dp = std::default_delete<Mesh>; std::unique_ptr<_Tp, _Dp>::pointer = Mesh*]
       unique_ptr(pointer __p) noexcept
       ^
/usr/include/c++/4.8/bits/unique_ptr.h:141:7: note:   no known conversion for argument 1 from ‘__gnu_cxx::__alloc_traits<std::allocator<Mesh> >::value_type aka Mesh’ to ‘std::unique_ptr<Mesh>::pointer aka Mesh*’
/usr/include/c++/4.8/bits/unique_ptr.h:135:17: note: constexpr std::unique_ptr<_Tp, _Dp>::unique_ptr() [with _Tp = Mesh; _Dp = std::default_delete<Mesh>]
       constexpr unique_ptr() noexcept
                 ^
/usr/include/c++/4.8/bits/unique_ptr.h:135:17: note:   candidate expects 0 arguments, 1 provided
make: *** [obj/testRender.o] Errore 1

请我不明白错误在哪里,我有一个Mesh 的向量并使用operator[] 给我一个Mesh 并以此创建一个unique_ptr&lt;Mesh&gt;

谢谢。

PS。这些是我的课:

#ifndef _MODEL_H
#define _MODEL_H

#include "Mesh.h"
#include <vector>

#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>

class Model

    public:

        std::vector<Mesh> meshes;
        std::string directory;
        void loadModel(std::string path);
        void processNode(aiNode* node, const aiScene* scene);
        Mesh processMesh(aiMesh* mesh, const aiScene* scene);
;

#endif


#ifndef _MESH_H
#define _MESH_H

#include "Vec3d.h"
#include "Ray.h"
#include <vector>

class Mesh

    protected:
        unsigned int numVertices, numFaces;
        std::vector<unsigned int> vertexIndex;
        std::vector<Vec3d> verts;
        std::vector<Vec3d> vertexNormals;
        Vec3d cl;

    public:

        Mesh(unsigned int &_numVertices, unsigned int &_numFaces, std::vector<unsigned int> &_vertexIndex, std::vector<Vec3d> &_verts, std::vector<Vec3d> &_vertexNormals);
        bool intersect(Ray &r, double &t, double &u, double &v);
        inline const Vec3d getCL() return cl; 
;

#endif

【问题讨论】:

【参考方案1】:

使用函数std::make_unique代替构造函数(第27行):

std::unique_ptr<Mesh> myMesh = std::make_unique (myModel.meshes[0]);

包含&lt;memory&gt; 以使用std::make_unique

【讨论】:

它给了我错误:“make_unique”不是“std”的成员 你是否包含了 他在 C++11 模式下编译。 std::make_unique 直到 C++14 才存在。【参考方案2】:

您将myMesh 声明为std::unique_ptr&lt;Mesh&gt;,因此您应该使用默认值(nullptr)对其进行初始化

 std::unique_ptr<Mesh> myMesh; // initialized to nullptr

或使用 指针 指向 已分配 Mesh;像

 std::unique_ptr<Mesh> myMesh( new Mesh(/* arguments to constructor */) );

问题是您尝试使用Mesh 初始化myMesh(不是指向Mesh 的指针)

 std::unique_ptr<Mesh> myMesh( myModel.meshes[0] );
                            // myModel.meshes[0] is a Mesh

std::unique_ptr&lt;T&gt; 没有接收T 对象的构造函数;例如,您可以在 this page 中看到它。

注意:避免将指向myModel.meshes[0]的指针传递给myMesh构造函数,因为不是分配的Mesh;这将是错误和危险的。

【讨论】:

所以不可能使用我存储在 myModel 中的矢量网格中的网格? 我为我的 Mesh 类编写了一个复制分配和 costructor 以及一个 move assignment 和 costructor,但是当我在这里尝试使用它们时: std::unique_ptr myMesh( new Mesh(/* arguments到构造函数 */) );移动/复制 costructor 给了我这个错误:错误:'operator=' 不匹配(操作数类型是 'std::unique_ptr' 和 '__gnu_cxx::__alloc_traits<:allocator> >::value_type aka Mesh') @Oliver.A - 抱歉,如果您不向我们展示您的新代码,则很难猜出问题【参考方案3】:

类网格

#include "Mesh.h"
#include "Ray.h"
#include "Triangle.h"
#include <vector>

Mesh::Mesh(unsigned int &_numVertices, unsigned int &_numFaces, std::vector<unsigned int> &_vertexIndex, std::vector<Vec3d> &_verts, std::vector<Vec3d> &_vertexNormals)

    numVertices = _numVertices;
    numFaces = _numFaces;
    vertexIndex = std::move(_vertexIndex);
    verts = std::move(_verts);
    vertexNormals = std::move(_vertexNormals);
    cl = Vec3d(0.5, 0.5, 0.5);



Mesh::Mesh(const Mesh& m) // Copy constructor

    numVertices = m.numVertices;
    numFaces = m.numFaces;
    vertexIndex = m.vertexIndex;
    verts = m.verts;
    vertexNormals = m.vertexNormals;
    cl = m.cl;


Mesh& Mesh::operator=(const Mesh& m) // Copy assignment

    numVertices = m.numVertices;
    numFaces = m.numFaces;
    vertexIndex = m.vertexIndex;
    verts = m.verts;
    vertexNormals = m.vertexNormals;
    cl = m.cl;

    return *this;


Mesh::Mesh(Mesh&& m) // Move constructor

    numVertices = m.numVertices;
    numFaces = m.numFaces;
    vertexIndex = std::move(m.vertexIndex);
    verts = std::move(m.verts);
    vertexNormals = std::move(m.vertexNormals);
    cl = m.cl;

    m.numVertices = 0;
    m.numFaces = 0;
    m.cl = Vec3d();


Mesh& Mesh::operator=(Mesh&& m) // Move assignment

    numVertices = m.numVertices;
    numFaces = m.numFaces;
    vertexIndex = std::move(m.vertexIndex);
    verts = std::move(m.verts);
    vertexNormals = std::move(m.vertexNormals);
    cl = m.cl;

    m.numVertices = 0;
    m.numFaces = 0;
    m.cl = Vec3d();

    return *this;

类模型

#include "Model.h"
#include "Mesh.h"
#include "Vec3d.h"

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <vector>

#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>

Model::Model(std::string path)

    std::cout << "Model constructor " << std::endl;
    this->loadModel(path);


void Model::loadModel(std::string &path)

    std::cout << "Load Model " << std::endl;
    // Read file via ASSIMP

    Assimp::Importer importer;
    const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices);
    // Check for errors 
    if(!scene || scene->mFlags == AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) // if is Not Zero
    
        std::cout << "ERROR::ASSIMP:: " << importer.GetErrorString() << std::endl;
        return;
    

    // Retrieve the directory path of the filepath
    this->directory = path.substr(0, path.find_last_of('/'));

    // Process ASSIMP's root node recursively
    this->processNode(scene->mRootNode, scene);


// Processes a node in a recursive fashion. Processes each individual mesh located at the node and repeats this process on its children nodes (if any).
void Model::processNode(aiNode* node, const aiScene* scene)

    std::cout << "Process node " << std::endl;
    // Process each mesh located at the current node
    for(unsigned int i = 0; i < node->mNumMeshes; i++)
    
        // The node object only contains indices to index the actual objects in the scene. 
        // The scene contains all the data, node is just to keep stuff organized (like relations between nodes).
        int meshIndex = node->mMeshes[i];
        aiMesh* mesh = scene->mMeshes[ meshIndex ]; 
        this->meshes.push_back(this->processMesh(mesh, scene));         
    
    // After we've processed all of the meshes (if any) we then recursively process each of the children nodes
    for(unsigned int i = 0; i < node->mNumChildren; i++)
    
        this->processNode(node->mChildren[i], scene);
    



Mesh Model::processMesh(aiMesh* mesh, const aiScene* scene)

    std::cout << "Process Mesh " << std::endl;
    // Data to fill
    std::vector<Vec3d> verts;
    std::vector<Vec3d> vertexNormals;
    std::vector<unsigned int> vertexIndex;

    // Walk through each of the mesh's vertices
    for(unsigned int i = 0; i < mesh->mNumVertices; i++)
    
        std::cout << "Process vertex ";
        Vec3d position, normal;

        // Positions
        if ( mesh->mVertices )
        
            std::cout << " position ";
            position.setX((double)mesh->mVertices[i].x);
            std::cout << " position.x " << position.getX();
            position.setY((double)mesh->mVertices[i].y);
            std::cout << " position.y " << position.getY();
            position.setZ((double)mesh->mVertices[i].z);
            std::cout << " position.z " << position.getZ();
        

        // Normals
        if ( mesh->mNormals )
        
            std::cout << " normal ";
            normal.setX((double)mesh->mNormals[i].x);
            normal.setY((double)mesh->mNormals[i].y);
            normal.setZ((double)mesh->mNormals[i].z);
        

        std::cout << std::endl;
        verts.push_back(position);
        vertexNormals.push_back(normal);
    
    // Now wak through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices.
    for(unsigned int i = 0; i < mesh->mNumFaces; i++)
    
        std::cout << "Process face" << std::endl;
        aiFace face = mesh->mFaces[i];
        // Retrieve all indices of the face and store them in the indices vector
        for(unsigned int j = 0; j < face.mNumIndices; j++)
        
            vertexIndex.push_back(face.mIndices[j]);
            std::cout << face.mIndices[j] << std::endl;
        

        std::cout << "" << std::endl;
    

    // Return a mesh object created from the extracted mesh data
    std::cout << "Return mesh" << std::endl;
    return Mesh(mesh->mNumVertices, mesh->mNumFaces, vertexIndex, verts, vertexNormals);

主类

 #include "RenderEngine.h"
#include "Cam.h"
#include "Vec3d.h"
#include "Mesh.h"
#include "Model.h"
#include <vector>
#include <memory>

#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>

struct Option

    int imageWidth, imageHeight;
;

int main()

    Cam* cam = new Cam(Vec3d(0.0, 0.0, 10000.0), Vec3d(0.0, 0.0, -1.0), 90, 1);
    //Cam* cam = new Cam();
    Option option;
    option.imageWidth = 512;
    option.imageHeight = 512;

    //option.imageWidth = 1920;
    //option.imageHeight = 1080;

    //option.imageWidth = 1280;
    //option.imageHeight = 900;
    std::string path = "model/cube.obj";
    Model myModel(path);
    //myModel.loadModel();
    std::vector<std::unique_ptr<Mesh>> objects;

    //std::unique_ptr<Mesh> myMesh = std::make_unique (myModel.meshes[0]); //first try

    std::unique_ptr<Mesh> myMesh; // initialized to nullptr
    myMesh = (myModel.meshes[0]);   //second try

    //myMesh = new Mesh(myModel.meshes[0].numVertices, myModel.meshes[0].numFaces, myModel.meshes[0].vertexIndex, myModel.meshes[0].verts, myModel.meshes[0].vertexNormals);
    //std::unique_ptr<Mesh> myMesh( new Mesh(myModel.meshes[0].numVertices, myModel.meshes[0].numFaces, myModel.meshes[0].vertexIndex, myModel.meshes[0].verts, myModel.meshes[0].vertexNormals) );

    objects.push_back(std::move(myMesh));

    RenderEngine* render = new RenderEngine(*cam, option.imageWidth, option.imageHeight);

    render->getImage(objects);

    delete cam;
    delete render;

    return 0;


        render->getImage(objects);

        delete cam;
        delete render;

        return 0;
    

并且有这个错误:

testRender.cpp: In function ‘int main()’:
testRender.cpp:39:9: error: no match for ‘operator=’ (operand types are ‘std::unique_ptr<Mesh>’ and ‘__gnu_cxx::__alloc_traits<std::allocator<Mesh> >::value_type aka Mesh’)
  myMesh = (myModel.meshes[0]);   //second try
         ^
testRender.cpp:39:9: note: candidates are:
In file included from /usr/include/c++/4.8/memory:81:0,
                 from RenderEngine.h:13,
                 from testRender.cpp:1:
/usr/include/c++/4.8/bits/unique_ptr.h:190:7: note: std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(std::unique_ptr<_Tp, _Dp>&&) [with _Tp = Mesh; _Dp = std::default_delete<Mesh>]
       operator=(unique_ptr&& __u) noexcept
       ^
/usr/include/c++/4.8/bits/unique_ptr.h:190:7: note:   no known conversion for argument 1 from ‘__gnu_cxx::__alloc_traits<std::allocator<Mesh> >::value_type aka Mesh’ to ‘std::unique_ptr<Mesh>&&’
/usr/include/c++/4.8/bits/unique_ptr.h:203:2: note: template<class _Up, class _Ep> typename std::enable_if<std::__and_<std::is_convertible<typename std::unique_ptr<_Up, _Ep>::pointer, typename std::unique_ptr<_Tp, _Dp>::_Pointer::type>, std::__not_<std::is_array<_Up> > >::value, std::unique_ptr<_Tp, _Dp>&>::type std::unique_ptr<_Tp, _Dp>::operator=(std::unique_ptr<_Up, _Ep>&&) [with _Up = _Up; _Ep = _Ep; _Tp = Mesh; _Dp = std::default_delete<Mesh>]
  operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
  ^
/usr/include/c++/4.8/bits/unique_ptr.h:203:2: note:   template argument deduction/substitution failed:
testRender.cpp:39:9: note:   ‘__gnu_cxx::__alloc_traits<std::allocator<Mesh> >::value_type aka Mesh’ is not derived from ‘std::unique_ptr<_Tp, _Dp>’
  myMesh = (myModel.meshes[0]);   //second try
         ^
In file included from /usr/include/c++/4.8/memory:81:0,
                 from RenderEngine.h:13,
                 from testRender.cpp:1:
/usr/include/c++/4.8/bits/unique_ptr.h:211:7: note: std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(std::nullptr_t) [with _Tp = Mesh; _Dp = std::default_delete<Mesh>; std::nullptr_t = std::nullptr_t]
       operator=(nullptr_t) noexcept
       ^
/usr/include/c++/4.8/bits/unique_ptr.h:211:7: note:   no known conversion for argument 1 from ‘__gnu_cxx::__alloc_traits<std::allocator<Mesh> >::value_type aka Mesh’ to ‘std::nullptr_t’
make: *** [obj/testRender.o] Errore 1

【讨论】:

以上是关于std::unique_ptr<Mesh>::unique_ptr(__gnu_cxx::__alloc_traits<std::allocator<Mesh> >的主要内容,如果未能解决你的问题,请参考以下文章

如何将 std::sort() 与 std::unique_ptr<[]> 一起使用?

调整 std::vector<std::unique_ptr<T>> 大小的性能

std::list< std::unique_ptr<T> >:传递它

std::unique_ptr的用法

智能指针unique_ptr记录

如何调整 std::vector<std::queue<std::unique_ptr<int>>> 的大小?