Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板参数包序列化_C++ - Fatal编程技术网

C++ 模板参数包序列化

C++ 模板参数包序列化,c++,C++,我需要创建一个模块化序列化程序。我正在使用msgpack 因此,一个简单的表单如下所示: enum class FieldId { Time, Pressure }; struct TimeFieldConfig { typedef long long DataType; const static FieldId id = FieldId::Time; } struct PressureFieldConfig { typedef double DataType; co

我需要创建一个模块化序列化程序。我正在使用msgpack

因此,一个简单的表单如下所示:

enum class FieldId
{
  Time,
  Pressure
};

struct TimeFieldConfig
{
  typedef long long DataType;
  const static FieldId id = FieldId::Time;
}

struct PressureFieldConfig
{
  typedef double DataType;
  const static FieldId id = FieldId::Pressure;
}

struct BaseField
{
  virtual void dump(std::ofstream &buffer) const = 0;
};

template<class T>
struct Field : BaseField
{
  void dump(std::ofstream &buffer)
  {
    msgpack::pack(buffer, values);
  }
  std::vector<typename T::DataType> values;
}

struct Recorder
{
    template <class T>
    void insertField()
    {
        data.insert_or_assign(T::id, new Field<T>);
    }

    template <class T>
    void add(const typename T::DataType &v)
    {
        if (data.find(T::id) != data.cend())
            reinterpret_cast<Field<T> *>(data[T::id])->add(v);
    }

    void dump(const std::string fpath)
    {
        std::ofstream outFile;
        outFile.open(fpath, std::ios::binary);

        // headers
        std::vector<int> keys;
        for (const auto &k : data)
            keys.push_back(static_cast<int>(k.first));
        msgpack::pack(outFile, keys);

        // values
        for (const auto &k : data)
            k.second->dump(outFile);

        outFile.close();
    }

    std::map<FieldId, BaseField *> data;
}

int main(int arc, char* argv[])
{
  Recorder r;
  r.insertField<TimeFieldConfig>();
  r.insertField<PressureFieldConfig>();

  /* add data ... */
  r.dump("data.dat");
}
枚举类字段ID
{
时间
压力
};
结构TimeFieldConfig
{
typedef长数据类型;
const static FieldId=FieldId::Time;
}
结构压力场配置
{
typedef双数据类型;
常量静态字段id=字段id::压力;
}
结构基场
{
虚拟空转储(流和缓冲区的std::of)常量=0;
};
模板
结构字段:基本字段
{
无效转储(流和缓冲区的标准::)
{
msgpack::pack(缓冲区、值);
}
std::向量值;
}
结构记录器
{
模板
void insertField()
{
插入或赋值(T::id,新字段);
}
模板
void add(const typename T::DataType&v)
{
if(data.find(T::id)!=data.cend())
重新解释(数据[T::id])->添加(v);
}
无效转储(const std::string fpath)
{
std::出流管;
open(fpath,std::ios::binary);
//标题
向量键;
用于(常量自动和k:数据)
键。向后推(静态施法(k.first));
msgpack::pack(输出文件、密钥);
//价值观
用于(常量自动和k:数据)
k、 第二->转储(输出文件);
outFile.close();
}
地图数据;
}
int main(int弧,字符*argv[]
{
记录器r;
r、 insertField();
r、 insertField();
/*添加数据*/
r、 转储(“data.dat”);
}
转储工作正常,所有数据和标题都存在。 现在我想加载回记录的数据


我的问题是如何创建一个动态插入所需字段的
记录器的实例

我自己回答,以防有帮助

我想要创建的是命名为注册表模式。 我就是这样做的

// may be a singleton
class FieldFactory
{
public:
    FieldFactory()
    {
    }
    ~FieldFactory()
    {
    }

    template <class T>
    void registerField()
    {
        creators.insert_or_assign(T::id, &Field<T>::creator);
    }

    BaseField *create(FieldId fid)
    {
        return creators[fid]();
    }

private:
    typedef std::function<BaseField *()> FieldCreator;
    std::map<FieldId, FieldCreator> creators;
};

我想可能会有所改进,但这就是我的想法。

这太宽泛了-你已经尝试过什么?你在哪里卡住了?
FieldFactory ff;
ff.registerField<TimeFieldConfig>();
ff.registerField<PressureFieldConfig>();
static BaseField *creator()
{
  return new Field<T>();
}
void reload(const std::string &filePath)
{
    std::ifstream inFile;
    inFile.open(filePath, std::ios::binary);

    std::vector<char> buffer((std::istreambuf_iterator<char>(inFile)), (std::istreambuf_iterator<char>()));
    inFile.close();

    // headers
    std::size_t off = 0;
    std::vector<int> keys;

    msgpack::object_handle result;
    msgpack::unpack(result, buffer.data(), buffer.size(), off);
    result.get().convert(keys);

    // create fields
    for (auto k : keys)
    {
        FieldId fid = static_cast<FieldId>(k);
        data.insert_or_assign(fid, m_ff->create(fid));
    }

    // values
    for (auto k : keys)
    {
        msgpack::object_handle oh;
        msgpack::unpack(oh, buffer.data(), buffer.size(), off);

        FieldId fid = static_cast<FieldId>(k);
        if (data.find(fid) != data.cend())
            data[fid]->reload(oh);
    }
}