Зерновые не поддерживают необработанные указатели

Редактировать: Название вопроса было основано на глубоком непонимании ошибки компилятора, которую я получил. Я (глупо) предположил, что ошибка заключалась в том, что я пытался десериализовать объект, который я объявил внутри функции. Это было совершенно неправильно. Я сам не предпринимал достаточных усилий по отладке, иначе я мог бы выяснить, что не так. Так что название было довольно вводящим в заблуждение, и я изменил его. Спасибо Андрею Беньковскому за помощь.


Я пишу функции сериализации для 3D-моделей в своем движке, используя хлопья, которые оказались действительно эффективными и простыми в использовании. До сих пор все работало отлично, когда я тестировал (де-) сериализацию простой сетки. Но теперь я пытаюсь десериализовать другой класс, но столкнулся с проблемой, которую не понимаю.

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

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

Это мой класс, который нужно десериализовать:

struct DescriptionFile 
{
public:
    DescriptionFile(){}

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

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

Это дает мне ошибку компилятора: Cereal не поддерживает сериализацию необработанных указателей - используйте умный указатель, даже если это не указатель. В другой части кода что-то подобное работает просто отлично. Я был бы рад, если бы кто-нибудь помог мне решить эту проблему.


person LukeG    schedule 26.10.2015    source источник
comment
filepath это std::string? Пожалуйста, отредактируйте свой вопрос, чтобы указать тип.   -  person Андрей Беньковский    schedule 26.10.2015
comment
использование пространства имен — зло   -  person Андрей Беньковский    schedule 26.10.2015


Ответы (1)


Я никогда не использовал Cereal, но похоже, что он ожидает, что вы будете использовать что-то вроде этого:

map<string, unique_ptr<MeshDescription> >

Чтобы получить std::unique_ptr, я обычно #include <memory>

Из документации по зерновым:

хлопья поддерживают сериализацию интеллектуальных указателей, но не тупых указателей (то есть необработанных указателей, таких как int *) или ссылок. Поддержку указателя можно найти, включив <cereal/types/memory.hpp>.

Может быть, это означает, что вы должны включить их заголовок вместо стандартного.

P.S. Когда ваш объект владеет ресурсами (например, динамически выделяемыми MeshDescription), всегда делегируйте управление ресурсами (выделение, освобождение, копирование и т. д.) отдельному классу (умный указатель, коллекция, оболочка и т. д.). См. правило 0.

person Андрей Беньковский    schedule 26.10.2015
comment
Это, вероятно, сработает, но мне все еще интересно, ПОЧЕМУ мой код не компилируется. Как я уже сказал, я использовал что-то подобное (практически то же самое, но с другой структурой), работает абсолютно нормально, без нареканий. Я хочу использовать реальное решение или понять, что происходит, и не использовать обходной путь для странного поведения. - person LukeG; 26.10.2015
comment
P.S. Я уже делаю это. Код, который я опубликовал, находится в классе RessourceManager. - person LukeG; 26.10.2015
comment
Ладно, я тупой. Я думал, что ошибка была внутри функции loadFile, хотя на самом деле это был тот факт, что я использую карту, состоящую из указателя в качестве значения. Спасибо за вашу помощь. - person LukeG; 26.10.2015
comment
1. std::unique_ptr, std::shared_ptr и std::weak_ptr — управляемые указатели из стандартной библиотеки. Они тщательно протестированы и оптимизированы. Я бы порекомендовал вам использовать эти классы для управления вашими указателями, если только нет веской причины создавать свои собственные. 2. Вы неправильно понимаете суть управления ресурсами: каждый экземпляр диспетчера ресурсов должен управлять только одним экземпляром ресурса, а не набором ресурсов. Попробуйте и посмотрите, насколько более безопасный и простой код вы получите в результате. - person Андрей Беньковский; 26.10.2015
comment
1. Я знаю, что такое умные указатели и где их использовать, я просто не понял ошибку компилятора, которую я получил. 2. Есть причина, по которой мне нужны все мои ресурсы (по крайней мере, некоторых видов) в одном месте/классе. - person LukeG; 26.10.2015
comment
По какой причине? Почему нельзя использовать std::map<std::string, std::unique_ptr<MeshDescription>> или что-то подобное? - person Андрей Беньковский; 26.10.2015