6

Edit: The question title was based on a deep missunderstanding of the compiler error I got. I was (sillyly) assuming the error was, that I tried to deserialize to an object I declared inside of the function. This was utterly wrong. I didn't do enough debug efforts myself or I could have found out what was wrong. So the title was quite missleading and I changed it. Thanks to Андрей Беньковский for helping.


I'm writing Serialization functions for 3D Models in my engine using cereal, which proves to be really efficient and easy to use. So far everything worked great when I tested (de-)serializing a simple Mesh. But now I'm trying to deserialize another class but ran in a problem I don't get.

void loadFile(std::string filepath)
{
    DescriptionFile file;

    {
        ifstream stream = ifstream(filepath, std::ifstream::binary);
        PortableBinaryInputArchive archive(stream);
        archive(file);
        stream.close();
    }
}

This is my class, that should be deserialized:

struct DescriptionFile 
{
public:
    DescriptionFile(){}

    map<string, MeshDescription*> meshDescriptions;
    map<string, ModelDescription*> modelDescriptions;

public:
    template<class Archive>
    void serialize(Archive & archive)
    {
        archive(meshDescriptions, modelDescriptions);
    }
};

It gives me compiler error: Cereal does not support serializing raw pointers - please use a smart pointer Even though it's not a pointer. In another part of the code something similar works just fine. I'd be glad if somebody could help me solve this.

LukeG
  • 638
  • 10
  • 20

1 Answers1

4

I never used Cereal, but it looks like it expects you to use something like this:

map<string, unique_ptr<MeshDescription> >

To get std::unique_ptr I usually #include <memory>

From cereal documentation:

cereal supports serializing smart pointers but not dumb pointers (that is to say raw pointers, such as int *) or references. Pointer support can be found by including <cereal/types/memory.hpp>.

May be it means you have to include their header instead of the standard.

P.S. When your object owns resources (e.g. dynamically allocated MeshDescription) always delegate resource management (allocation, deallocation, copying, etc) to a separate class (smart pointer, collection, wrapper, etc). See rule of 0.

Quentin
  • 62,093
  • 7
  • 131
  • 191
  • This would probably work, but I'm still wondering WHY my code does not compile. As I said, I used something similar (practically the same, but with a different struct) works absolutely fine without complaining. I want to use the real solution or understand what's happening and don't use some workaround for strange behaviour. – LukeG Oct 26 '15 at 13:25
  • P.S. I'm already doing this. The code I've posted is located in a class called RessourceManager. – LukeG Oct 26 '15 at 13:26
  • Okay, I'm stupid. I though the error was inside of the loadFile function while indeed it was the fact that I'm using a map consisting of a pointer as value. Thanks for your help. – LukeG Oct 26 '15 at 13:53
  • 1
    1. `std::unique_ptr`, `std::shared_ptr` and `std::weak_ptr` are managed pointers from the standard library. They are highly tested and optimized. I'd recommend you using this classes to manage your pointers unless there is a very good reason to create your own. 2. You are misunderstanding the whole point of resource management: each instance of a resource manager should manage only one instance of a resource, not a collection of resources. Try it and see how much safer and simpler code you'll get in result. – Андрей Беньковский Oct 26 '15 at 14:01
  • 1. I know what smart pointers are and where to use them, I just missunderstood the compiler error I got. 2. There's a reason I need all of my ressources (at least of some kinds) in one place/class. – LukeG Oct 26 '15 at 14:09
  • What reason? Why can't you use `std::map>` or something similar? – Андрей Беньковский Oct 26 '15 at 14:17