yaml-cpp,YAML :: Node和模板运算符>>

时间:2011-11-01 21:02:47

标签: c++ templates yaml-cpp

我正在使用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支持的普通类型。

1 个答案:

答案 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版本中修补它。