• bind重载的类的非静态成员


    头文件

    #include <functional>
    

    实现

    // 实现一个通用的apdu准备的函数,通过调用p方法来实现协议的wrap和发送
    // 方法 p 来将 apdu 打包为[head][apdu][tail]
    // 这里我们想让 protocolUse 是一个函数指针
    template<typename protocolUse,typename flagType>
    
    void packDlmsHandAndSend(Meter* mtr,CGXDLMSSecureClient& gx,DLMS_COMMAND type,protocolUse p,flagType flag)
    {
        p(mtr, bufout[0],flag);
    }
    

    一个类想调用这个方法

    // 类自身的底层包装,发送函数,即 protocolUse
    int IEC46::sendToMeter(void)
    {
        return  0;
    }
    
    int IEC46::sendToMeter(Meter *meter, CGXByteBuffer &subGxData, IEC46::comTypeEnum flag)
    {
        return  sendToMeter(meter, Buffer(subGxData.GetData(), subGxData.GetSize()), flag);
    }
    
    // 这个是函数的类型,注意这里不能使用 mm来取代Fun
    // bind 的返回是 function 不是简单的函数指针 
    // typedef int (*mm)(Meter *meter, CGXByteBuffer &subGxData, IEC46::comTypeEnum flag);
    
    typedef std::function<int (Meter *meter, CGXByteBuffer &subGxData, IEC46::comTypeEnum flag)> Fun;
    using mysend = int(IEC46::*)(Meter *meter, CGXByteBuffer &subGxData, IEC46::comTypeEnum flag);
    
    // 1. 绑定一个函数,这里可以直接使用auto bindFunc2
    // 这里的类型声明 mysend 不可省略,因为有重载的同名成员函数,如果没有同名的,可以省略
    Fun bindFunc2 = std::bind((mysend)&IEC46::sendToMeter,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3);
    // 2. 调用形式可以省略掉 <Fun,IEC46::comTypeEnum>
    packDlmsHandAndSend<Fun,IEC46::comTypeEnum>(mtr,gxClient,DLMS_COMMAND_DISCONNECT_REQUEST,bindFunc2,comTask);
    
    
    //3. 精简的形式可以如下:
    using mysend = int(IEC46::*)(Meter *meter, CGXByteBuffer &subGxData, IEC46::comTypeEnum flag);
    auto bindFunc2 = std::bind((mysend)&IEC46::sendToMeter,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3);
    packDlmsHandAndSend(mtr,gxClient,DLMS_COMMAND_DISCONNECT_REQUEST,bindFunc2,comTask);
    
    
    

    简单一点的形式

    其实在这里,我们可以直接传递类为模版到packDlmsHandAndSend,然后调用p.sendToMeter(xxx)

    iec46下的成员函数,调用
    	makeApdu(type,sendByIec46)	 发送数据
    更理想的应该是
    
    iec46类下面有个发送函数,调用 makeApdu ,最终发送数据
    
  • 相关阅读:
    c#基础之集合
    找出子字符串在字符串中的所有索引
    c# 排序
    C#基础之枚举
    验证用户名不为空并且不存在
    验证用户名和密码,输入三次不正确就锁定账号
    c#基础
    linux使用
    python之logging模块
    手写MyBatis,纯手工打造开源框架(第三篇:运筹帷幄)
  • 原文地址:https://www.cnblogs.com/zongzi10010/p/13822840.html
Copyright © 2020-2023  润新知