簡體   English   中英

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

[英]yaml-cpp, YAML::Node, and a template operator >>

我正在使用yaml-cpp進行某種序列化。 為此,每個類都必須使用簽名聲明一個方法:

template <typename T> void Serialize(T& s);

保存和加載時, T是不同的類。 這兩個類的接口是相同的,但是由於大多數方法都是模板,因此我無法創建抽象基類。 這部分工作正常。 我試圖將其與YAML::Nodeoperator>>YAML::Emitteroperator<<掛鈎。

對於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>>嘗試了相同的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)都忽略它,並使用在nodeimp.h(yaml-cpp的一部分)中定義的operator>>

template <typename T>
inline void operator >> (const Node& node, T& value) {
    if(!ConvertScalar(node, value))
        throw InvalidScalar(node.m_mark);
}

所以我的問題是:我該如何解決? 我絕對希望的是只有一種用於序列化和反序列化的方法,並且能夠使用>>和<<,就像yaml-cpp支持的普通類型一樣。

首先,關於reinterpret_cast :您實際上需要static_cast 在您的情況下,您知道val T (而不僅僅是Serializable<T> ),因此可以直接將其強制轉換。

在這里,我假設您正在聲明您的課程,例如

class Foo: public Serializable<Foo> { ... };

reinterpret_cast會將val字節解釋為T ,這不能保證能正常工作,但可能會在您的情況下起作用,因為您具有單個繼承並且Serializable<T>不添加任何成員變量。

接下來,解決您的實際問題:這是yaml-cpp中的錯誤,現在已修復(如果您要跟上Mercurial存儲庫的話, 則已修復r52790a15757d ,請參閱http://code.google.com/p/yaml- cpp / issues / detail?id = 126 (我打開的問題)。

通過以上修復,我相信您的代碼應該可以工作。 如果您不了解存儲庫,那么差異就很小-您可以在yaml-cpp版本中對其進行修補。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM