3

我想尋找一個MPL序列生成Boost MPL爲對象序列化生成代碼?

class Object 
{ 
    string a; 
    int b; 
    long c; 
    char d; 
}; 

串行/解串碼,但我需要能夠識別對象並獲取回爲好,我想不通我怎麼會得到它的成員的名字,我必須知道它

代碼看起來應該像

void SerializeObject(ostream os) 
{ 
    serialize(object.a, os); 
    serialize(object.b, os); 

    //serialize(object.member, os); 
} 

我想用戶只定義相應的對象佈局的MPL序列生成上面的代碼,是可行的,你可以給我一些提示?

我的目的是:

用戶對上述對象定義mpl::vector<String, int, long, char>和我的metaprogram可以生成編碼需要的。

+0

我不認爲你可以得到你的成員的名字沒有一些嚴重的黑客攻擊。考慮如果你有兩個整數會發生什麼。 boost :: mpl如何知道哪個int是哪個? – 2011-05-16 19:48:45

+0

@Boaz,我不在乎,只要我以同樣的順序得到兩個int,就可以通過它們了。 – 2011-05-16 19:51:53

回答

2

有沒有辦法推斷模板中的成員名稱。你需要明確指定的一切,就像這樣:

template<typename ObjT, typename MemberT, MemberT ObjT::*Ptr> 
struct member{}; 

mpl::vector 
< 
    member<Object, string, &Object::a>, 
    member<Object, int, &Object::b>, 
    member<Object, long, &Object::c>, 
    member<Object, char, &Object::d> 
>; 

另一種選擇是創建功能,幫助生成member,定義爲operator>>member它們合併成一個member_vecoperator>>member_vec是併入更大的member_vec。既然你只使用類型,編譯器可以優化掉任何實際的函數調用

函數可以使用隱式模板參數,因此它可以使串行拿少一點代碼來定義:

auto serializer = 
     mem(&Object::a) >> 
     mem(&Object::b) >> 
     mem(&Object::c) >> 
     mem(&Object::d); 

我我自己製作了序列化器,使用了這兩種技術。第二個是我最滿意的。

10

考慮boost::fusion,並使用宏BOOST_FUSION_ADAPT_STRUCT()來將您的結構推廣到融合序列(隨機存取),例如,一旦你定義上面的結構,你可以這樣做

BOOST_FUSION_ADAPT_STRUCT(
    Object, 
    (std::string, a) 
    (int, b) 
    (long, c) 
    (char, d) 
) 

現在,它的被提拔,你可以簡單地用一個for_each遍歷成員,是這樣的:

template<typename archive> 
struct serializer { 
    serializer(archive& ar):ar(ar) {} 

    template<typename T> 
    void operator()(const T& o) const { 
     ar & o; // assuming binary for example... 
    } 
    archive& ar; 
}; 

template<typename archive, typename sequence> 
void serialize(archive& ar, sequence const& v) { 
    boost::fusion::for_each(v, serializer<archive>(ar)); 
} 

要它應該如此簡單:

Object foo; // instance to serialize 
serialize(<archive>, foo); 
0

您可以使用mpl::string來表示成員名稱。在我的應用程序中,我會做一些代碼生成,它會發出類似下面的內容。

typedef mpl::string < 'n', 'a', 'm', 'e' > name; 

您可以使用mpl::c_str <name>::value來獲取字符串表示形式。即「名稱」。

我存儲一個這樣的成員名稱序列,成員指針的另一個序列,將它們壓縮在一起,然後使用boost :: fusion查詢算法之一來查找給定成員名稱的成員指針。

如果您有興趣,我會發布代碼。目前我無法訪問它,因爲它位於我的家用PC中。