[C++技能提升]类型归一

最近在设计AI调用架构时,想把各个AI功能的接口定义统一并用基类的多态管理起来(即各个AI功能都继承自同一个基类,并重写init、run、release这三个接口),遇到一个问题就是AI的输入数据类型多样化(除了基本数据类型int、float等外,还有图像、mesh、点云等)且参数个数不固定,想过用模板函数的方式声明这三个接口但是不支持virsual重写。

因此最终想到的方案是:

对于接口参数数量不固定的问题,采用std::vector容器包装起来,于是接口可以定义成:

#include<vector>
class BaseAIModule{
    public:
    virsual bool init(const std::vector<DataType>& params)=0;
    virsual bool run(const std::vector<DataType>& params,std::vector<DataType>& outs)=0;
    virsual bool release()=0;
    protected:
    std::string moduleName;
}

 对于类型统一的问题(vector容器只能存放同一种类型的数据,c++17有其他容器可支持不同类型数据的存放),如果把DataType定义为每个参数的地址,则接口内部无法做类型校验(当然也可以再把类型名称也放入到另一个vector容器一起传入,但是这样不美观且操作繁琐)。因此我的解决方案是用类继承的方式管理,我的实现代码如下:

// aidata.h
#ifndef AI_DATA_H_
#define AI_DATA_H_

/* Useage:
double* pd=new double(3.45);
std::vector<std::shared_ptr<BaseAIData>> params={
    AIDATA(int,1),AIDATA(float,2),AIDATA(double*,pd)};
std::cout<<"param 0:"<<GET_DATA(int,params[0])<<std::endl;
std::cout<<"param 1:"<<GET_DATA(int,params[1])<<std::endl;
std::cout<<"param 2:"<<GET_DATA(int,params[2])<<std::endl;
*/

#include<string>
#include<iostream>

// 包装数据
#define AIDATA(Type,Data) std::shared_ptr<BaseAIData>(new AIData<Type>(Data,#Type))

// 获取数据
#define GET_DATA(Type,ptrBaseAIData) ptrBaseAIData->get_data<Type>(#Type)

template<typename T> class AIData;

class BaseAIData{
    public:
    std::string get_type(){
        return type;
    }

    bool check_type(const std::string& type){
        if(type!=this->type){
            std::cout<<"Error:check type fail."<<std::endl;
            return false;
        }
        return true;
    }

    template<typename T>
    T get_data(const std::string& type){
        T data;
        if(!check_type(type)){
            return data;
        }
        AIData<T>* ptr=static_cast<AIData<T>*>(this);
        return ptr->get_data();
    }
    
    protected:
    std::string type;
};

template<typename T>
class AIData:public BaseAIData{
    public:
    AIData(const T& data,const std::string& type){
        this->data=data;
        this->type=type;
    }

    T get_data(){
        return data;
    }

    private:
    T data;
}
#endif

那么,最终的接口可以定义成:

#include<vector>
#include"BaseAIData.h"

// 基类
class BaseAIModule{
    public:
    virsual bool init(const std::vector<std::shared_ptr<BaseAIData>>& params)=0;
    virsual bool run(const std::vector<std::shared_ptr<BaseAIData>>& params,std::vector<std::shared_ptr<BaseAIData>>& outs)=0;
    virsual bool release()=0;
    protected:
    std::string moduleName;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值