低版本CJson反序列化方案
现在的API接口普遍使用Json语法来描述,API的返回通常使用类似这样的结构:{ "code": 0, "message": "", "data": {...} }
即所有API都有code和message属性以表示成功或错误,它和业务是无关的;其它属性/数据则在data中定义,它和业务是相关的。
这种情况在C# / JAVA 中做反序列化时一般用泛型表示,如:class MyAPI { public int x; public int y; } class ApiResponse { public int code; public string message; public T data; } ApiResponse resp = JsonConvert.DeserializeObject>(...);
C++的处理方案由于RTTI(Runtime Type Information运行时类型信息)并不包含属性名等信息,无法通过反射找到类/结构的属性,因此无法实现C# / JAVA那种看起来比较优雅的写法。
github上解决这个问题的项目很多,但它们许多要求使用c++17或20以上的版本,由于我的项目限制只能使用c++14,因此我只看c++11或14的解决方案。
这些项目的解决方案大体有两类:
1.提供更友好的读写属性的方法,比如通过["..."]["..."]层层嵌套,让用户更容易读写属性,但是它并没有完成在对象/结构实体上的映射和赋值,相当于这个工作得用户来做,因此它更像是只提供了一些序列化/反序列化的辅助方法,而不是完整的json和对象转化的解决方案,标星超过3万的https://github.com/nlohmann/json就是这种情况;
2.允许用户用通常的写法去定义类/结构,再通过宏去标识需要和json做映射的属性,完成类似其他语言的反射机制,当然它是在编译期实现属性定位而不是其他语言的运行期。
方案2在使用成本上相较方案1要小很多,也更符合主流方案的习惯。我看了几个项目,最后选了json_struct(https://github.com/jorgen/json_struct),它的解决方案是:
对于一个json串:{ "One" : 1, "Two" : "two", "Three" : 3.333 }
定义一个类:struct JsonObject { int One; std::string Two; double Three; JS_OBJ(One, Two, Three); };
JS_OBJ是用于解决反射问题的宏,也可以定义在类外面:struct JsonObject { int One; std::string Two; double Three; }; JS_OBJ_EXT(JsonObject, One, Two, Three);
反序列化:JS::ParseContext context(json_data); JsonObject obj; context.parseTo(obj);
由此可见,除了所有方案都要写的类/结构定义之外,为反序列化要做的也就只写几行代码而已,相对方案1是简单了很多的,与C# / JAVA的解决方案相当。
回到最初的需求:{ "code": 0, "message": "", "data": {...} }
这个结构是嵌套的,无法使用类似于C# / JAVA 的写法:class MyAPI { public int x; public int y; } class ApiResponse { public int code; public string message; public T data; } ApiResponse resp = JsonConvert.DeserializeObject>(...);
json_struct的文档和examples中也没有提供明确的案例可以参考。
我试了一下,可以这样来定义:struct ApiResponse { int code; string message; JS_OBJ(code, message); } struct MyApiData { int x; int y; JS_OBJ(x, y); } struct MyAPI : public ApiResponse { MyApiData data; JS_OBJ(data); }
然后这样解析就可以了:JS::ParseContext context(...); MyAPI myApi; context.parseTo(myApi);
上述写法,相较C# / JAVA,C# / JAVA是用ApiResponse来包MyAPI(泛型传参),C++是用MyAPI来包ApiResponse(子类继承),并将子属性data从MyAPI拆出来,相当于多定义了一级,从语法上似乎稍微累赘一点,但整体结构还是清晰直观的。
物流新版图畅通双循环物畅其流百业兴,当下,我国正在加快构建以国内大循环为主体国内国际双循环相互促进的新发展格局。打通双循环,高效便捷的现代流通体系是基础。今年前十个月,全国社会物流总额达到275。4万
房价将迎来一次反弹整个2022年,国内整体的房价是缺乏资金进入的,大部分城市的房价都是慢速的下降,国家也在调控来保住房价。2023年,目前的经济形势来看,一二线的房子有希望再涨一点,政府已经在大力鼓
画里有话丨严查公职人员违规挂证中央纪委国家监委网站韩思宁漫画李硕近日,贵州省住房和城乡建设厅发布关于二级建造师涉嫌挂证人员有关情况的通报,公布19365名涉嫌挂证注册二级建造师名单,并提出具体核实认定查处要求,
大平原(二百九十五)腊八节腊八节文张鸿志腊八节的晚上,家人喝完腊八粥,我就用黄桃和苹果罐头瓶子准备腌制腊八蒜。外孙女茜茜对腊八粥不感兴趣,对罐头也不屑一顾。只对制作腊八蒜感兴趣,一连串问道什么是腊八蒜?咋个
每一眼都是惊艳!南沙这片超美的水杉林红了近日,随着深冬的到来,位于南沙区榄核镇的大坳村,水杉逐渐红了!一幅美丽的水乡风情画卷又映入眼帘,成为众多摄影发烧友的打卡点。水杉有植物界活化石之称。喜欢生长在气候温暖湿润光照充足的
热闹非凡!怀化体彩为大乐透1853万大奖诞生地授牌近日,怀化市锦溪南路192号4312012645体彩投注站格外热闹。店门口锣鼓喧天,红色拱门和横幅向人们传递着热烈祝贺本站购彩者喜中超级大乐透1853万元的喜讯。该站于12月12日
加大投资力度关注创新企业!大湾区企业考察团走访南沙佛山季华实验室90后博士研发的新型非充气轮胎一定很有应用前景!我们将加大对大湾区的投资力度,重点关注一些已经崭露头角的创新企业!12月22日,粤港澳大湾区全球招商大会举行企业考察活动。
乾隆帝将自己的出生地改为寺庙,藏着怎样的抱负?位于北京紫禁城东北方的雍和宫,以其多民族建筑风格融合的皇家宫院气派,佛寺丛林的庄严肃穆和精美神秘的藏传佛教艺术珍品,吸引着五洲四海的香客宾朋。雍和宫曾为雍正皇帝的行宫,将行宫改为藏
感染后,老人和小孩的症状相差很大随着放开后第一波感染的高潮的到来,身边已经有一半以上都感染了,但是症状却各不相同。这一波对于成年人来说,确实就是一个大号感冒,我旁边的朋友基本都已经阳康了,经历过打摆子,发烧,咳嗽
白肺病的症状由于新冠肺炎的不断变异,现在对新冠肺炎的治疗也发生变化主要以自身免疫力为主,但是也导致了许多病发症而白肺病就是目前流行较广泛的一种死亡性极高的疾病,这种病治疗的关键在于寻找病因并及
莫泰尤纳斯已到国内,CBA迎来大结局根据媒体人国蓝当自强报道,原新疆外援莫泰尤纳斯已抵达中国,目前在江苏接受隔离。与此同时,有网友发现莫泰的推特地点就在国内,更进一步证实了这个消息。此前孟祥宇就在直播上爆料,莫泰已签