我正在使用yaml-cpp进行某种序列化。为此,每个类都必须使用签名声明一个方法:
template <typename T> void Serialize(T& s);
保存和加载时T
是另一个类。这两个类的接口是相同的,但我不能创建一个抽象基类,因为大多数方法都是模板。这部分工作正常。我试图将其与YAML::Node
的{{1}}和operator>>
YAML::Emitter
联系起来。
对于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>>
但是gcc(4.6.2)和clang(2.9)都忽略它,并使用nodeimp.h中定义的template <typename T>
void operator>>(const YAML::Node& node,
Serializable<T>& val)
{
Deserializer deserializer(node);
reinterpret_cast<T*>(&val)->Serialize(deserializer);
}
(yaml-cpp的一部分):
operator>>
所以我的问题是:我应该如何解决这个问题?我绝对想要的是只有一种方法用于序列化和反序列化,并且能够使用&gt;&gt;和&lt;&lt ;,好像是yaml-cpp支持的普通类型。
答案 0 :(得分:0)
首先,关于reinterpret_cast
:您实际上需要static_cast
。在您的情况下,您知道val
是T
(而不只是Serializable<T>
),因此您可以直接投放。
在这里,我假设你宣布你的课程如
class Foo: public Serializable<Foo> { ... };
reinterpret_cast
会将val
的字节解释为T
,但不保证可以正常工作,但可能适用于您的情况,因为您有单继承和Serializable<T>
不添加任何成员变量。
接下来,关于你真正的问题:这是yaml-cpp中的一个错误,现在它已修复(r52790a15757d如果你跟上mercurial存储库,并看到http://code.google.com/p/yaml-cpp/issues/detail?id=126问题我打开了。)
通过上述修复,我相信您的代码应该可行。如果你没有跟上存储库,那么差异非常小 - 你可以在你的yaml-cpp版本中修补它。