c++如何打印函数地址_如何优雅的实现C++编译期静态反射

原文链接:如何优雅的实现C++编译期静态反射 | Netcan_Space​www.netcan666.com部门请来了软件专家袁英杰咨询师指导我们软件开发,从中我也学到了很多姿势,在此记录下来宝贵的经验。苹果的mbp品控真是差劲,写这个东西把LShift键按坏了,真是难受。反射能做什么最近和大师聊软件设计,其中一个点是关于反射,反射最大的作用就是序列化、解序列化一个结构体,然后就能够在各个模块之...
摘要由CSDN通过智能技术生成

原文链接:

如何优雅的实现C++编译期静态反射 | Netcan_Space​www.netcan666.com

部门请来了软件专家袁英杰咨询师指导我们软件开发,从中我也学到了很多姿势,在此记录下来宝贵的经验。苹果的mbp品控真是差劲,写这个东西把LShift键按坏了,真是难受。

反射能做什么

最近和大师聊软件设计,其中一个点是关于反射,反射最大的作用就是序列化、解序列化一个结构体,然后就能够在各个模块之间进行通信交互,不管是跨进程也好,还是跨机器也好,都缺不了反射这个功能,这也是OO世界对象交互的载体。

不然就需要人工手写一堆序列化、反序列代码,不仅代码难看,而且工作量大,容易出错。印象最深的一个例子是,大师在一个电信项目,模块之间通过TLV格式的消息进行通信,而这些TLV格式也是内部实现的,还不是标准的,然后大师定义了一套机制,只需要统一声明一次元数据的信息,然后通过include不同头文件,就能对同一个元数据进行不同的解释,比如序列化、解序列到数据库,序列化、解序列到网络,这也是预编译多态技术,仅用C++98的特性就能做到。

举一个直观一点的例子,比如打印一个结构体内容(其实就是把结构体转换成字符串):

struct Point {
    
    double x;
    double y;
};
Point p {
     1, 2 };

那么你可能会这样写:

printf("Point x = %d y = %d", p.x, p.y);

如果有成千上百个结构体,对应的打印函数(序列化到字符串)也就成千上百个,如果利用反射手段,只需要写一次,就能给所有反射对象自动生成打印函数(转换)代码。

引子

后来我在C++社区看到一个讨论,说C++20在元编程方面提供了很多便利,其中最大的遍历就是if-constexpr,再也不用模式匹配写一堆enable_if了,然后题主给了一个例子,用C++20的模板元求结构体的字段数量,代码如下:

struct AnyType {
    
    template <typename T>
    operator T();
};

template <typename T>
consteval size_t CountMember(auto&&... Args) {
    
    if constexpr (! requires {
     T{
     Args... }; }) {
     // (1)
        return sizeof...(Args) - 1;
    } else {
    
        return CountMember<T>(Args..., AnyType{}); // (2)
    }
}

int main(int argc, char** argv) {
    
    struct Test {
     int a; int b; int c; int d; };
    printf("%zun", CountMember<Test>());
}

看到这坨代码,我愣了一会,然后问大师这个求结构体字段数量是怎么做到呢?C++目前最大缺陷是缺少静态反射能力(这里指的是语言层面提供的静态反射信息,C++23估计会落地),应该很难做到的,分析了一会,终于看懂了,太巧妙了:

  • AnyType声明了类型转换操作符(《C++ Modern design》书中的术语是稻草人函数),可以转换成任意类型
  • 分支(2)通过不断构造所求类型T = Test,当无法构造时(1),也就是输入的参数过多,这时候参数个数 - 1就是字段个数。

那么只能C++20才能做到么?这里主要用到了C++17if-constexpr特性,C++11可以通过enable-if做到,而最主要的是那个requiresC++20才支持conceptC++17都无法做到。

然后我思考了一下,类型构造,《C++ Modern design》这本书讲过,用sizeof做类型推导,给的一个例子是

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值