標籤:

目前是否有C++提案是關於在編譯期獲取類/結構體成員變數的?

受到一個序列化庫的啟發(cereal cereal Docs - Main)。這個庫優勢在於只需要對每個類/結構體定義 serialize 或 save/load 函數便可以序列化/反序列化任意這些類的組合實例,擴展性極強。官網上有一段示例代碼,拷貝如下:

#include &
#include &
#include &
#include &

struct MyRecord
{
uint8_t x, y;
float z;

template &
void serialize( Archive ar )
{
ar( x, y, z );
}
};

struct SomeData
{
int32_t id;
std::shared_ptr&&> data;

template &
void save( Archive ar ) const
{
ar( data );
}

template &
void load( Archive ar )
{
static int32_t idGen = 0;
id = idGen++;
ar( data );
}
};

int main()
{
std::ofstream os("out.cereal", std::ios::binary);
cereal::BinaryOutputArchive archive( os );

SomeData myData;
archive( myData );

return 0;
}

對於大部分類/結構體而言,上述 serialize 函數的定義非常直觀。

我個人覺得:

  1. 編譯器對於每一個類/結構體默認定義一個 serialize (或其它名字的)函數似乎並不困難,譬如對於上述代碼中 MyRecord 中定義的 serialize,其功能僅僅是遍歷類中成員即可;編譯器可以默認生成一個 serialize函數,也可以由人工自定義 serialize,如上述代碼中的 SomeData,甚至添加 = delete 來刪除默認定義。類似拷貝構造函數的實現機理。
  2. 通過使用 cereal 中已經實現的模版技術,一個通用的 serialize 函數(或其他名字)可以激發更加廣泛的用途,譬如可以實現通用的 class/struct 與 tuple之間的轉換,實現通用的==比較運算(比較內容是否完全一致),實現通用的 randomize 函數來隨機化任意類的數據 。。。任何涉及遍歷成員變數的功能都能比較方便地實現出來,而無須再對每一個特定的類添加特定的函數定義。

有點語無倫次。。那麼問題來了。。。。

目前 C++ 提案中是否有與此相關的討論?如果有的話相關提案進展如何,大概何時能進入標準呢?

非常感謝~


serialize到text怎麼辦,xml怎麼辦,json怎麼辦,vczh我高中的時候創建的專用格式怎麼辦,小端binary怎麼辦,大端binary怎麼辦,不同的格式要跳過不同的field怎麼辦,有的int格式化10進位有的16進位怎麼辦,是不是以後出一個新格式都要有一個interface給你插入?這還有完沒完?


1.目前有靜態反射的提案.坐等C++17加入,如果有靜態反射,編譯期自舉自身成員不是問題

2.你說的這種方式不太可能進入標準,怎麼可以入侵式的給每個類加一個輔助序列化函數.如果用C++的人沒這個需求確負擔了不該有的代價.與C++的設計原則相悖

3.你說的這個我覺得開放編譯器的API給應用程序使用比較好


請使用rust-lang的

#[deriving(Decodable, Encodable)]

標記(答非所問,逃


是不是有點破壞兼容性了


上次看到這種, 是msgpack的c++包裝用到, 結論是比較彆扭難用, 當然如果擴展好了另當別論.


Type Driven Wire Protocols with Boost Fusion · Thomas Rodgers Blog

看看這個


反射。。。。。。


protobuf嘛,相當於結構體定義在.proto文件中,而且二進位化兼容性好


推薦閱讀:

如今C++在非底層環境下還有多少地位?
為什麼非指針對象不能使用const成員函數?
迭代器尾後元素的設計是出於什麼意圖?
關於C++中的override?

TAG:C | 編譯器 | C11 |