2011-02-13 48 views
5

因此,我正在研究一種文件格式,用於存儲在某種範圍內定義的結構化數據。最簡單的例子是隨着時間的推移浮動值,但我設計它允許在每個點上有多個維度和任意數據。我想將數據的結構存儲在文件頭中,因爲它會考慮到一些整潔的功能。在C++中內省結構體定義?

起初我還以爲我有用戶使用的類層次建立自己的數據結構,所以你可以做這樣的事情:

pf_type data = record(PF_DOUBLE) (
        record("position")(
        field("xp") & 
        field("yp") & 
        field("zp")) & 
        record("velocity")(
        field("xv") & 
        field("yv") & 
        field("zv")) & 
        record("acceleration")(
        field("xa") & 
        field("ya") & 
        field("za"))); 

這將等價於C這樣的事情:

struct { 
    struct position { 
     double xp,yp,zp; 
    } 
    struct velocity { 
     double xv,yv,zv; 
    } 
    struct acceleration { 
     double xa,ya,za; 
    } 
} 

這並不可怕,但它仍然需要用戶單獨定義AC結構來當讀/寫數據實際使用。

我認爲它會很整潔,如果他們可以定義一個常規的c-struct,它們傳遞給我的庫,並且我對它進行了內省以獲取寫入該文件的信息。雖然我不知道在C++中是否可以遠程執行此類操作。我的想法是,它可能使用了一些模板元編程魔法,但它會非常混亂。所以我想我會從那些對C++有更多瞭解的人那裏尋求一些想法。

+2

你基本上建立一個DSL,而且也沒有圍繞着需要努力獲得。 – wheaties

+2

我同意小麥的做法,但讓我更積極地提出它:你正在做的是一個好主意 - 即它是一個合理的設計,不要讓我們勸阻你。但是你自己在這裏,C++對這類工作幾乎沒有任何幫助。 –

+0

這就是我的想法,我想我基本上必須使用模板編寫一個結構解析器,ick。 –

回答

7

不是究竟是你在找什麼,但可能是一個很好的靈感來源,將是Google's Protobufs。他們採取的方法與您在問題中討論的方法略有不同。使用protobuf,首先在.proto文件中描述數據結構,然後使用protobuf編譯器(protoc)codegens樣板代碼爲幾種不同語言之一(包括C++)提供樣板代碼。

編碼的代碼完全能夠反映在.proto文件中定義的結構,以及什麼protobuf最適合於串行化二進制數據以通過線路發送。顯然,你會付出一點點的性能上的打擊,但它會給你帶來一些真正的高質量反思,並且簡單訪問的性能指標並不是那麼高。

基本上,你的圖書館的客戶可以通過你填寫protobuf。通過直接呼叫您或通過網絡呼叫。

+0

這可能是我最終走的路,我真的想保持一切自我思想...... –

3

模板機械太原始了,無法合理地做這種東西。在我看來,更好的選擇是有一個單獨的易於編輯和易於解析的文件來描述數據結構,然後從該定義生成所需的C++代碼。然而,用C++編寫代碼生成器很煩人,因爲C++ I/O,解析,格式設置和字符串操作都不是最理想的,我的建議是使用Python或其他very high level language

然後,一切都可能被放入一個具有適當依賴關係的Makefile中(即,如果描述文件更改,則會重新生成C++文件),因此構建仍然是自動的。

擁有一個「普通」C++文件而不是模板欺騙會讓你的生活變得更容易(編譯時間,錯誤消息,編譯器對硬核模板的不兼容性,支持調試生成的代碼)。

+0

我完全同意......直到最後一段中不必要的爭論和狂熱。除去一個更好的答案,但除此之外,這與sblom的答案很接近,除了一般的術語而不是描述protobufs。 –

+2

@Fred Nurk:好的......我承認過度反應了。但令人驚訝的是,IMO對C++社區採取了這樣一種不必要的使用模板方法。許多C++程序員正在砸牆,以便能夠使用糟糕的工具解決非問題。 – 6502

+0

許多程序員將自己鎖定在單一語言中,錯過了代碼生成等的優點,而不是構建自己的工具箱並組合多個工具。 IDE需要你加強設計師的工作方式,而不是結合更簡單的工具(比如make,儘管它有嚴格的限制,但其他的構建系統也存在),以適合你的項目。同樣,我也喜歡Python,但其他工具可以填補這個空白。 –

0

Boost.Fusion提供了一些整潔的技巧來爲C++帶來編譯時反射,對你而言,你會對BOOST_FUSION_ADAPT_STRUCT感興趣。

如果您希望添加補充重載,例如可以從字符串獲取字段。你需要添加一些補充能力。

整個事情可以用宏和模板來完成......但我寧願與protobuf堅持;)