Pregunta

EDIT: Created a minimal VS solution to make it easier to reproduce the error: https://www.dropbox.com/s/pk0t8t2xykjmtc5/test%20cereal%20this.zip (add cereal in includes instead of $(LIBSROOT) where I have it).

I get 2 errors stating that I have no default constructor:

error C2139: 'Node' : an undefined class is not allowed as an argument to compiler intrinsic type trait '__is_constructible'

error C2338: Trying to serialize a an object with no default constructor.
<path>\cereal\details\traits.hpp line 1248

But I think the classes' default constructors should be fine. If I comment out the serialization of Node class variables I get the same errors but with Part class variables.

I have the following code structure (some parts like include guards or unrelated code were omitted, I can of course provide the whole thing if needed, but I wanted to keep it as short as possible):

Shape.h:

#include <cereal/types/memory.hpp>
#include <cereal/types/vector.hpp>
#include <string>

class Part;
typedef std::shared_ptr<Part> PartPtr;
class Node;
typedef std::shared_ptr<Node> NodePtr;

class Shape {
private:
    std::vector<PartPtr> parts;
    NodePtr root;
    std::vector<std::vector<NodePtr>> levels;


public:
    Shape();
    Shape(std::string fileName);

    template <class Archive>
    void serialize(Archive & ar) {
        ar(parts, levels, root);
    }
};

Shape.cpp:

#include "Shape.h"
#include "Node.h"
#include "Part.h"

Shape::Shape() {
}

Shape::Shape(std::string fileName) {
    // omitted code
}

Node.h:

#include "PointCloud.h"

#include <cereal/types/vector.hpp>
#include <cereal/types/memory.hpp>

class Part;
typedef std::shared_ptr<Part> PartPtr;
class Node;
typedef std::shared_ptr<Node> NodePtr;

class Node : public std::enable_shared_from_this<Node> {
private:
    std::vector<PartPtr> parts;
    NodePtr parent;
    PointCloud pointCloud;

public:
    Node();
    Node(std::vector<PartPtr> parts, NodePtr parent);

    template <class Archive>
    void serialize(Archive & ar) {
        ar(parts, parent, pointCloud);
    }
};

Node.cpp:

#include "Node.h"
#include "Part.h"

Node::Node() {
}

Node::Node(std::vector<PartPtr> parts, NodePtr parent) : parts(parts), parent(parent) {
    // code omitted
}

Part.h:

#include "PointCloud.h"
#include <cereal/types/memory.hpp>
#include <cereal/types/vector.hpp>

class Contact;
class Part;
typedef std::shared_ptr<Contact> ContactPtr;
typedef std::shared_ptr<Part> PartPtr;

class Part : public std::enable_shared_from_this<Part> {
private:
    PointCloud pointCloud;
    std::vector<ContactPtr> contacts;
public:
    Part();
    Part(double diameter);

    template <class Archive>
    void serialize(Archive & ar) {
        ar(pointCloud, contacts);
    }
};

Part.cpp:

#include "Part.h"
#include "Contact.h"

Part::Part() {
}

Part::Part(double diameter) {
    // omitted code
}

Contact class contains a PartPtr as a member variable, PointCloud contains just a bunch of Eigen::Matrix data (should probably be a smart pointer too, to speed up the code, but that shouldn't be important for this problem).

Any suggestions how to fix this? Or could it possibly be a bug? I am using VS2013, which could be the cause as well.

¿Fue útil?

Solución

You have only declared class Part;and class Node; in Shape.h. To use a class as template parameter you the compiler also needs a definition of that class. Include Part.h and Node.h in your Shape.h file. Also include Part.hin Node.h and Contact.h in Part.h. And put some include guards into the headers:

#ifndef SOME_UNIQUE_IDENTIFIER
#define SOME_UNIQUE_IDENTIFIER

// content of your header goes here

#endif

SOME_UNIQUE_IDENTIFIER would usially be something like NODE_H in your Node.h file and PART_H in your Part.h file.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top