模板参数包序列化
Template parameter pack serialization
我需要创建一个模块化序列化器。我正在使用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");
}
转储工作正常,所有数据和标题都存在。现在我想加载录制的数据。
我的问题是如何创建Recorder
的实例,哪些动态插入了所需的字段?
我回答自己,以防万一它会有所帮助。
我想创建的内容命名为注册表模式。这就是我这样做的方式。
// 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>();
}
并在Recorder
类中创建负载函数:
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);
}
}
我想可能有所改善,但这就是主意。
相关文章:
- 如何在C++中序列化结构数据
- 序列化,没有库的整数,得到奇怪的结果
- 如何知道QDataStream不能反序列化某些内容
- 如何使用Python从C++中读取谷物序列化数据
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 带有Protobuf序列化的C++Hazelcast:字符串不是UTF-8格式的
- 自定义对象的dlib序列化在gcc中失败
- C++boost序列化多态性问题
- 增强基于 XML class_id的反序列化
- 提升反序列化对象具有 nan 或 -nan 值
- 在 cpp 中的平面缓冲区中序列化对象
- 每次进行继承时都需要提升::序列化::base_object吗?
- 如何在 c++ 非托管代码中反序列化 byte[] 的 json 字符串?
- 提升序列化 1:73 的向后兼容性问题
- 对模板化类链使用可变参数模板来生成序列化
- C++ Boost - 序列化错误 - 将"const B"作为"this"参数
- 在对象序列化期间添加额外参数是否有更好的方法?
- 谷物/C++ 11 - 如何指定反序列化的可选参数
- 模板参数包序列化
- C++ Boost::序列化"no matching function for call"到我的加载函数参数中类的构造函数