我正在使用yaml-cpp进行某种序列化。为此,每个类都必须使用签名声明一个方法:
template <typename T> void Serialize(T& s);
T
保存和加载时这是一个不同的类。这两个类的接口是一样的,但是我不能做一个抽象基类,因为大多数方法都是模板。这部分工作正常。我试图将它与YAML::Node
'soperator>>
和YAML::Emitter
's连接起来operator<<
。
因为operator<<
,我有一个可行的解决方案,尽管非常残酷。首先为所有可序列化的类声明一个超类:
template <typename T> class Serializable {};
然后我可以使用以下内容operator<<
:
template <typename T>
YAML::Emitter& operator<<(YAML::Emitter& out,
Serializable<T>& val)
{
Serializer serializer(out);
reinterpret_cast<T*>(&val)->Serialize(serializer);
return out;
}
到目前为止,这很有效,尽管这reinterpret_cast
看起来很可怕,而且我不确定它是否合法。我已经尝试过相同的方法operator>>
,但没有奏效。它看起来像这样:
template <typename T>
void operator>>(const YAML::Node& node,
Serializable<T>& val)
{
Deserializer deserializer(node);
reinterpret_cast<T*>(&val)->Serialize(deserializer);
}
但是 gcc (4.6.2) 和 clang(2.9) 都忽略它,并使用operator>>
nodeimp.h 中定义的(yaml-cpp 的一部分):
template <typename T>
inline void operator >> (const Node& node, T& value) {
if(!ConvertScalar(node, value))
throw InvalidScalar(node.m_mark);
}
所以我的问题是:我应该如何解决这个问题?我绝对想要的是只有一个方法用于序列化和反序列化,并且能够使用 >> 和 <<,就像它是 yaml-cpp 支持的普通类型一样。