- 主题:这个json序列化、反序列化的库看着还可以
静态反射是语言特性,编译时完成,也不是模板技巧,所有类型信息编译器都有,编译器暴露接口给程序取这些信息很直接。
【 在 hgoldfish 的大作中提到: 】
: 静态反射也需要额外存储类型信息的吧。
:
: C++ 现在已经有 typeid() 了。为了实现楼主说的 JSON 序列化与反序列化就必须细化到函数和属性级。那存储的类型信息就太多了。
: ...................
--
修改:milksea FROM 123.139.87.*
FROM 123.139.87.*
用过你写的第一个,自己写to_json()/from_json()
【 在 z16166 的大作中提到: 】
: 哪N个?
: 这个也得自己搞std::wstring,而且每个struct要提供to_json()/from_json(),也比较啰嗦。
: 倒是也搞了类似的宏NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE/NLOHMANN_DEFINE_TYPE_INTRUSIVE
: ...................
--
FROM 111.207.199.*
to_json()/from_json()比jsoncpp那种手写大量代码从Json::Value里摘出来每个字段,要优雅一些,但每个struct要写这个还是有点啰嗦的
它定义的宏提供了to_json()/from_json()的默认实现,如果字段都是内置支持的类型的话,用这两个宏就够了:
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE、NLOHMANN_DEFINE_TYPE_INTRUSIVE
正在看这个nlohmann json怎么支持std::wstring,如果每个std::wstring类型的字段都要手动加一句转换utf8的代码,那也比较啰嗦。
这个网址可以生成std::wstring的代码,但这个正好是不怎么方便的那种:
https://app.quicktype.io/
cpp-json那个小库只要给std::wstring类型加个偏特化转成uft8,就可以支持,不用每个字段都加个转换utf8的语句。
【 在 CRonaldo31 的大作中提到: 】
: 用过你写的第一个,自己写to_json()/from_json()
--
FROM 123.118.191.*
wstring在windows上就是utf16,在linux上是utf32(或者说在win上适合存放utf16字符,在linux上适合存放utf32字符)
如果在linux上用utf16,需要自己处理utf16的surrogate pair吧,那其实比较麻烦,每个字符不等长。
windows上的api应该是可以直接处理utf16的surrogate pair。
当然,如果只是那26个英文字母的大小写,就不涉及到surrogate pair,把每个surrogate pair当作两个独立的utf16字符处理也能接受。
对utf16字符串,下面这种转换是buggy的实现:
std::wstring data = L"Abc";
std::transform(data.begin(), data.end(), data.begin(), [](wchar_t c){ return std::towlower(c); });
一是处理不了surrogate pair;二是某些语言的字符有问题,例子可以参考下面的:
https://en.cppreference.com/w/cpp/string/wide/towupper
https://en.cppreference.com/w/cpp/string/wide/towlower
我这边大部分字符串是用完就释放了,内存占用不是问题,需要转换大小写再匹配的场合,等长字符串处理方便,而且统一用std::wstring方便源代码跨平台(差异的部分用宏控制)
【 在 kirbyzhou 的大作中提到: 】
: 话说你们用wstring不嫌内存占用太大么?
: 而且wchar_t有16bit和32bit两种实现。
: 我一般都用u16string,偶尔用u32string
: ...................
--
修改:z16166 FROM 123.118.191.*
FROM 123.118.191.*
【 在 z16166 的大作中提到: 】
: wstring在windows上就是utf16,在linux上是utf32(或者说在win上适合存放utf16字符,在linux上适合存放utf32字符)
: 如果在linux上用utf16,需要自己处理utf16的surrogate pair吧,那其实比较麻烦,每个字符不等长。
: windows上的api应该是可以直接处理utf16的surrogate pair。
那你Windows上也不能简单的用towlower这种字符级API啊。
要确保没问题,还是用u32string比较方便。
你给的那两个网页上的麻烦例子是需要考虑字符上下文做整串转换才能解决问题的。
这估计得用ICU之类的复杂库了。
: ...................
--
修改:kirbyzhou FROM 220.249.52.*
FROM 220.249.52.*
CRT的函数估计不支持surrogate,
OS内置有一些支持
https://learn.microsoft.com/en-us/windows/win32/intl/surrogates-and-supplementary-characters
【 在 kirbyzhou 的大作中提到: 】
:
: 那你Windows上也不能简单的用towlower这种字符级API啊。
: 要确保没问题,还是用u32string比较方便。
: ...................
--
FROM 123.118.191.*
比较山寨的办法, 用宏 + std::tie + magic enum可以实现对带枚举的 struct 递归序列化和反序列化。 使用的时候类似用一个
STRUCT_REFLECTION(XXStruct, id, key, color, value)
不过在实际工程中没这么用,因为如果序列化了std::vector这种container, 或者带智能指针和多态的类型,在TypeScript或者别的语言不容易一行代码做反序列化。
--
FROM 66.152.176.*
目前阶段的反射只能用宏,或者预处理。
BitShares区块链的代码里也有一个反射框架,看着挺复杂的,宏用的boost PP。看名字好像支持继承的反射。
https://github.com/bitshares/bitshares-fc/blob/4d024a83b774da0e186c0c6c070e695f563da373/include/fc/reflect/reflect.hpp
这个不需要在宏里把每个成员再重复一遍
https://zhuanlan.zhihu.com/p/388454455
这是个动态反射
https://www.rttr.org/
【 在 emwanwei 的大作中提到: 】
: 比较山寨的办法, 用宏 + std::tie + magic enum可以实现对带枚举的 struct 递归序列化和反序列化。 使用的时候类似用一个
: STRUCT_REFLECTION(XXStruct, id, key, color, value)
: 不过在实际工程中没这么用,因为如果序列化了std::vector这种container, 或者带智能指针和多态的类型,在TypeScript或者别的语言不容易一行代码做反序列化。
--
修改:z16166 FROM 123.118.191.*
FROM 123.118.191.*