gpt4 book ai didi

c++ - 用于创建 SerializerManager 的模板魔法

转载 作者:行者123 更新时间:2023-11-28 02:49:58 24 4
gpt4 key购买 nike

我正在创建一个正在编辑数据的应用程序,然后需要以各种格式存储它。问题是该应用程序是使用插件架构构建的记住,所以我不知道需要预先存储哪些格式或哪些对象。

我想要完成的是一个 SerializeManager,您可以在其中动态注册支持的格式。

目标是能够创建一个对象,然后指定模板特化支持的格式。示例:

template<typename Type, typename Format>
void serialize(const Type& type, const Format& format)
{
}

class IFormat
{
public:
virtual ~IFormat(){}
};

class XmlFormat : public IFormat
{

};

class BinaryFormat : public IFormat
{

};

class MyDataToStore
{
public:
int m_data1; //Data to store
string m_data2; //Data to store
};

template<>
void serialize(const MyDataToStore& type, const XmlFormat& format)
{
//Serialization code goes here
}

我现在的目标是创建一个 SerializeManager 来管理所有格式并调用正确的特化。我希望它能像这样工作:

int main()
{
SerializeManager man;
man.RegisterFormat(".xml", std::shared_ptr<IFormat>(new XmlFormat())); // Where .xml is a key

MyDataToStore obj;

man.Store<MyDataToStore>(".xml", obj); //where .xml is a key
}

目标是在上面的 MyDataToStore、Xml 特化中结束,而不必在 Store 函数中将格式指定为模板参数。这可能吗?我已经尝试在 IFormat 类中使用一个纯虚函数来调用子类中的序列化函数,但是由于虚函数不能使用模板,所以我松开了 MyDataToStore 并调用了默认函数。

问候!

编辑:

如果有人想知道我采用了以下解决方案。我跳过了只需要在序列化/反序列化时指定扩展名的愿望。这是我的结果。

#include <string>

template<typename Formatter, typename Type>
void serialize(Formatter& format, Type& type)
{
static_assert(false, "No known serializer function found");
}

template<typename Formatter, typename Type>
void deserialize(Formatter& format, Type& type)
{
static_assert(false, "No known deserializer function found");
}

class SerializeManager
{
public:
SerializeManager(){}
virtual ~SerializeManager(){}

template<typename Type, typename Formatter>
bool Serialize(std::string filepath, Type & t)
{
Formatter format(filepath);
format.setManager(this);
serialize<Formatter, Type>(format, t);
return true;
}

template<typename Type, typename Formatter>
bool Serialize(Formatter& format, Type& t)
{
serialize(format, t);
return true;
}

template<typename Type, typename Formatter>
bool Deserialize(std::string filepath, Type & t)
{
Formatter format(filepath);
format.setManager(this);
deserialize<Formatter, Type>(format, t);
return true;
}

template<typename Type, typename Formatter>
bool Deserialize(Formatter& format, Type& t)
{
deserialize(format, t);
return true;
}


private:

};

class FormatterBase
{
public:
void setManager(SerializeManager* man)
{
m_manager = man;
}

SerializeManager* getManager()
{
return m_manager;
}

private:
SerializeManager* m_manager;
};

static_assert 有助于在未找到专用函数时引发编译器错误。似乎运作良好。用法:

#include "SerializeManager.h"

struct Human
{
template<typename T, typename S>
friend void serialize(T& t, S& s);

template<typename T, typename S>
friend void deserialize(T& t, S& s);

Human(int age, std::string name) : m_age(age), m_name(name){}

private:

int m_age;
std::string m_name;
};

class XmlSerializer : public FormatterBase
{
public:
XmlSerializer(std::string filepath){}

void NewNode(std::string name){}
};

template<>
void serialize(XmlSerializer& serial, Human& human)
{
//Do the serialization
}

int main()
{
SerializeManager man;
Human åke(15, "Åke");
man.Serialize<Human, XmlSerializer>("file.xml", åke);
}

最佳答案

我想你来不及走路就先跑了。

您需要的是一种中间格式。它可以是二进制的,也可以是名称/值对的树,这都无所谓。 重要的是一切都可以序列化为这种中间格式。

那么,这是一个简单的(哈!)用这种中间格式编写序列化程序的情况。 Xml、Json、二进制或任何其他您能想到的深奥格式。

关键是众所周知且定义明确的中间层。一旦有了它,另一端发生的事情就真的不重要了。

关于c++ - 用于创建 SerializerManager 的模板魔法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23303380/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com