netcan / netcan.github.io

My blog for something about programming.
https://netcan.github.io/
2 stars 1 forks source link

如何优雅的实现C++编译期静态反射 | Netcan on Programming #2

Open netcan opened 4 years ago

netcan commented 4 years ago

https://netcan.github.io/2020/08/01/%E5%A6%82%E4%BD%95%E4%BC%98%E9%9B%85%E7%9A%84%E5%AE%9E%E7%8E%B0C-%E7%BC%96%E8%AF%91%E6%9C%9F%E9%9D%99%E6%80%81%E5%8F%8D%E5%B0%84/

部门请来了软件专家袁英杰咨询师指导我们软件开发,从中我也学到了很多姿势,在此记录下来宝贵的经验。苹果的mbp品控真是差劲,写这个东西把LShift键按坏了,真是难受。 反射能做什么最近和大师聊软件设计,其中一个点是关于反射,反射最大的作用就是序列化、解序列化一个结构体,然后就能够在各个模块之间进行通信交互,不管是跨进程也好,还是跨机器也好,都缺不了反射这个功能,这也是OO世界对象交互的载体。 不然

yuqinw commented 3 years ago

你好,假如我要循环遍历这种嵌套结构体里面的所有成员和对应的值存到一个XML文件中要怎么实现呢?能不能用反射来实现,但是大概的思路是什么呢?

typedef struct _TABLE
{

struct

{ unsigned int a : 1; };

struct

{ unsigned int b : 1; };

}table, *table;
netcan commented 3 years ago

@yuqinw 你好,假如我要循环遍历这种嵌套结构体里面的所有成员和对应的值存到一个XML文件中要怎么实现呢?能不能用反射来实现,但是大概的思路是什么呢?

typedef struct _TABLE
{

struct

{ unsigned int a : 1; };

struct

{ unsigned int b : 1; };

}table, *table;

参考dumpObj,可以遍历拿到每个字段的field,以及字段名,那么可以通过名字索引到xml的entry获取得到值写入field,也可以通过field的值写到其字段名的xml文件中。

yuqinw commented 3 years ago

@yuqinw 你好,假如我要循环遍历这种嵌套结构体里面的所有成员和对应的值存到一个XML文件中要怎么实现呢?能不能用反射来实现,但是大概的思路是什么呢?

typedef struct _TABLE
{

struct

{ unsigned int a : 1; };

struct

{ unsigned int b : 1; };

}table, *table;

参考dumpObj,可以遍历拿到每个字段的field,以及字段名,那么可以通过名字索引到xml的entry获取得到值写入field,也可以通过field的值写到其字段名的xml文件中。

感谢你的回复,但是我现在的问题就是不知道怎么遍历这个复杂的结构的。

yuqinw commented 3 years ago

你好, 感谢你的来信,但是我现在的问题就是不知道应该怎么遍历这个结构体,结构体很大,里面有几百个unsigned int类型的成员。

------------------ 原始邮件 ------------------ 发件人: "netcan/netcan.github.io" <notifications@github.com>; 发送时间: 2020年10月15日(星期四) 下午5:34 收件人: "netcan/netcan.github.io"<netcan.github.io@noreply.github.com>; 抄送: "ヾ 莫醒"<2210690911@qq.com>;"Mention"<mention@noreply.github.com>; 主题: Re: [netcan/netcan.github.io] 如何优雅的实现C++编译期静态反射 | Netcan on Programming (#2)

@yuqinw 你好,假如我要循环遍历这种嵌套结构体里面的所有成员和对应的值存到一个XML文件中要怎么实现呢?能不能用反射来实现,但是大概的思路是什么呢? typedef struct _TABLE { struct { unsigned int a : 1; }; struct { unsigned int b : 1; }; }table, *table;
参考dumpObj,可以遍历拿到每个字段的field,以及字段名,那么可以通过名字索引到xml的entry获取得到值写入field,也可以通过field的值写到其字段名的xml文件中。

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

yarkey09 commented 3 years ago

思路不错,感谢分享

yarkey09 commented 3 years ago

这一段: (void(f(typename TDECAY::template FIELD<TDECAY, Is>(obj).name(), typename TDECAY::template FIELD<TDECAY, Is>(obj).value())), ...); 为什么不是: (f(typename TDECAY::template FIELD<TDECAY, Is>(obj).name(), typename TDECAY::template FIELD<TDECAY, Is>(obj).get()), ...);

请问加上 void() 的作用是有什么用意么?

netcan commented 3 years ago

这一段: (void(f(typename TDECAY::template FIELD<TDECAY, Is>(obj).name(), typename TDECAY::template FIELD<TDECAY, Is>(obj).value())), ...); 为什么不是: (f(typename TDECAY::template FIELD<TDECAY, Is>(obj).name(), typename TDECAY::template FIELD<TDECAY, Is>(obj).get()), ...);

请问加上 void() 的作用是有什么用意么?

如果f有返回值编译器会告警吧,仅仅是为了忽略返回值。

FlyAndNotDown commented 3 years ago

写的不错,受益匪浅

netcan commented 3 years ago

@yuqinw 你好,假如我要循环遍历这种嵌套结构体里面的所有成员和对应的值存到一个XML文件中要怎么实现呢?能不能用反射来实现,但是大概的思路是什么呢?

typedef struct _TABLE
{

struct

{ unsigned int a : 1; };

struct

{ unsigned int b : 1; };

}table, *table;

参考该项目:https://github.com/netcan/config-loader

enojoker commented 2 years ago

hello.. first of all. it's a great example of reflection in cpp. But I couldn't get the code compile following the example it seems that the PAIR or PARE macro didn't work as expected

this is the Point definition expand to following

struct Point { template <typename, size_t> struct FIELD; static constexpr size_t _fieldcount = 2; doublex, (double)y; template struct FIELD<T, 0> { T& obj; FIELD(T& obj): obj(obj) {} auto value() -> decltype(auto) { return (obj.x, (double)y); } static constexpr const char name() { return "EAT (double)x"; } }; PARE ; template struct FIELD<T, 0 + 1> { T& obj; FIELD(T& obj): obj(obj) {} auto value() -> decltype(auto) { return (obj.EAT ); } static constexpr const char name() { return "EAT"; } }; };

enojoker commented 2 years ago

you know what. it's working now. I'm working with visual studio 2019, for got to put in /Zc:preprocessor

netcan commented 2 years ago

the code in post doesn't verify in msvc, but I using the same tech in my project: https://github.com/netcan/config-loader, it works in msvc. @enojoker

Nu11able commented 7 months ago

写的很好,感谢分享

Kuwaaaa commented 3 months ago

非常好文章,一直想找一个简单的反射实现,现在这就是了。 补充一点,msvc的宏预处理器实现与标准不一样,会导致GET_ARG_COUNT失效。如果想在vs里编译需要额外设置一个选项: 项目->属性->配置属性->C/C++->预处理器->使用标准符合性预处理器 [是/Zc:preprocessor]

具体参考以下文章最后一段: https://zplutor.github.io/2021/07/14/how-to-get-argument-count-of-variable-argument-macro/