首页 > 解决方案 > 我想序列化一个包含整数的结构向量,但它不起作用(谷物库)

问题描述

我正在使用谷物库来序列化东西。我正在尝试使用 struct{ some unsingned short ints } 序列化 std::vector 类型的类成员。

编译器消息/usr/include/cereal/cereal.hpp:543 失败:错误:静态断言失败:谷物找不到提供的类型和存档组合的任何输出序列化函数。

用无符号短整数的 std::vector 替换要归档的数据直接按预期工作。有人可以告诉我我做错了什么,或者谷物是否甚至能够用结构来做到这一点?我不明白,因为显然支持任何类型的 int,并且在添加适当的包含后向量也是如此。只是将整数包装在结构中不起作用?

带有要序列化的东西的简化数据类:database.h

#include <utils/x_precompiled_headers.h>
#include <utils/serialize.h>
#include <database/datamodel.h>

class Database : public QObject
{
    Q_OBJECT

private:
    std::vector<Datamodel::model> models_;
    // std::vector<unsigned short int> test = {1,2,3};

void Database::SaveToDisk(){
    Serialize::ExportData(*this, "database");
}

void Database::LoadFromDisk(){
    Serialize::ImportData(*this, "database");
}

    // serialization
    friend class cereal::access;
    template<class Archive>
    void save(Archive &ar) const {
//                                   ar(test); // this does not complain
                                   ar(models_); //this gives the compiler error
                                 }
};

我要序列化的结构的定义头:database/datamodel.h

namespace Datamodel
{
    typedef struct{
        unsigned short int number1;
        unsigned short int number2;

        template<class Archive>
        void save(Archive &ar) const{
            ar(number1, number2);
        }

        template<class Archive>
        void load(Archive &ar) const{
            ar(number1, number2);
        }
    } model;
}

序列化类:utils/serialize.h

class Serialize
{
public:
    template<typename T>
    static void ExportData(T &object, const std::string &filename)
    {
        std::string path = std::filesystem::current_path() /= filename;
        std::ofstream ofs(path);

        if(ofs.is_open()){
            cereal::BinaryOutputArchive oarchive(ofs);
            oarchive(object);
            ofs.close();
        }
    }

    template <typename T>
    static void ImportData(T &object, const std::string &filename)
    {
        std::string path = std::filesystem::current_path() /= filename;

        if(!std::filesystem::exists(path))
            return;

        std::ifstream ifs(path);

        if(ifs.is_open())
        {
            cereal::BinaryInputArchive iarchive(ifs);
            iarchive(object);
            ifs.close();
        }
    }
};

预编译头文件,包含相关内容:x_precompiled_headers.h

#include <cereal/access.hpp>
#include <cereal/archives/binary.hpp>
#include <cereal/types/string.hpp>
#include <cereal/types/vector.hpp>

更新 1:好的,我现在已经更新了代码并为我的结构提供了序列化方法。我已更新 th OP 中的代码以反映更改。我还包括了我在 OP 的 database.h 中使用的保存和加载功能。可悲的是,它给了我这个编译器错误(/usr/include/cereal/cereal.hpp:822: error: no matching function for call to 'cereal::BinaryInputArchive::processImpl(const std::vectorDatamodel::model&)') .

标签: c++qtcereal

解决方案


Cereal 知道如何序列化标准类型,例如开箱即用的向量和整数,但不知道如何序列化Datamodel::model.

它也不知道开箱即用如何序列化Database,但你告诉它如何使用save

// serialization
    friend class cereal::access;
    template<class Archive>
    void save(Archive &ar) const {
//                                   ar(test); // this does not complain
                                   ar(models_); //this gives the compiler error
                                 }

您需要为Datamodel::model.

// serialization
friend class cereal::access;
template<class Archive>
void save(Archive &ar) const {
    ar(number1); 
    ar(number2); 
}

推荐阅读