• C++ ---使用RTTI和模板的一个问题记录


    背景:

    提供一个写log的接口,参数支持int,float,string,QString,char*等几个类型的输入。

    想法:

    接口为模板函数,并通过C++提供的type_info类获取输入参数的类型,在接口内部统一将参数转换为string,然后写入log。

    错误代码:

    //支持string QString 整型(会转为int输出)和浮点型(浮点会转为double输出)
        template<class T>
        int mDLLLogCatfunc(T log, int level = 0)
        {
            if ( level < logLevel )
            {
                return VIS_Result_PASS;
            }
            
            ///不用判断类型:如果有不支持的类型,编译时会检测到,并报错。
            //        QString logType = typeid (log).name();
            //        if ( logType.contains("short") || logType.contains("int") || logType.contains("float") || logType.contains("double") || logType.contains("int64") || logType.contains("basic_string")
            //             || logType.contains("QString") || logType.contains("char const *"))
            //        {
            //            ShiftLog happy(log);
            //            mMutexLog.lock();
            //            stringLog.push(happy.strLog);
            //            mMutexLog.unlock();
            //            qDebug()<< QString::fromStdString(happy.strLog);
            //            return VIS_Result_PASS;
            //        }
            QString logType = typeid (log).name();
            QString happy;
            if ( logType.contains("short") || logType.contains("int") || logType.contains("float") || logType.contains("double") || logType.contains("int64") )
            {
                happy = QString("%1").arg(log);
            }
            else if( logType.contains("basic_string") || logType.contains("char const *"))
            {
                happy = QString::fromStdString(log);
            }
            else if (logType.contains("QString") )
            {
                happy = log;
            }
            
            mMutexLog.lock();
            stringLog.push(happy);
            mMutexLog.unlock();
            
            return VIS_Result_PASS;
        }

    就按照想法把代码翻译出来,结果编译时报错。

    逻辑上没问题。但是编译时是会把if{...} else if{...} else if{...},都编译。模板函数会在实例化的时候进行编译,比如 mDLLLogCatfunc(88);  这个时候 if 没问题,但是后面两个 else if 就会报错,因为QString::fromStdString参数不支持,happy = log也是不支持 int 到QString的重载。这里的if{...} else if{...} else if{...}并不是#if  #elif。

    优化:

    //如果直接在模板函数中实现,会报错:编译会将全部代码都编译,所以会有某些类型无法转换
    class ShiftLog
    {
    public:
        ShiftLog(short &log);
        ShiftLog(int &log);
        ShiftLog(float &log);
        ShiftLog(double &log);
        ShiftLog(long long &log);
        ShiftLog(QString &log);
        ShiftLog(string &log);
        ShiftLog(const char* &log);
        string strLog;
    };
    
    
    
    class ViFunc
    {
    public:
        static ViFunc &GetViFunc()
        {
            static ViFunc viFunc("imgSys.dll");
            return viFunc;
        }
    
        int VI_DLLAlgorithm(string AlgorithmName, bool* wait, vector<cv::Mat> inMat, vector<string> inString, vector<int> inNum, vector<cv::Rect> inRect,
                            pstInputVar inVariable, vector<cv::Mat> *outMat, vector<string> *outstring,
                            vector<int> *outInt, vector<cv::Rect> *outRect);//调用AlgorithmName函数
    
        //支持string QString 整型(会转为int输出)和浮点型(浮点会转为double输出)
        template<class T>
        int mDLLLogCatfunc(T log, int level = 0)
        {
            if ( level < logLevel )
            {
                return VIS_Result_PASS;
            }
    
            ///不用判断类型:如果有不支持的类型,编译时会检测到,并报错。
    //        QString logType = typeid (log).name();
    //        if ( logType.contains("short") || logType.contains("int") || logType.contains("float") || logType.contains("double") || logType.contains("int64") || logType.contains("basic_string")
    //             || logType.contains("QString") || logType.contains("char const *"))
    //        {
    //            ShiftLog happy(log);
    //            mMutexLog.lock();
    //            stringLog.push(happy.strLog);
    //            mMutexLog.unlock();
    //            qDebug()<< QString::fromStdString(happy.strLog);
    //            return VIS_Result_PASS;
    //        }
    
            ShiftLog happy(log);
            mMutexLog.lock();
            stringLog.push(happy.strLog);
            mMutexLog.unlock();
            return VIS_Result_PASS;
        }
    
    private:
        ViFunc(const char* dllPath);
        ViFunc(const ViFunc &v);
        ViFunc operator =(const ViFunc &v);
    
        virtual ~ViFunc();
    
        //调算法
        HINSTANCE imgSysHandler;//加载ImgSys
        SysAlg mSysAlgorithm[MAX_FUNC_NUM];
        mutex mMutexFunc;//调用函数时,加锁
    
        //写Log
        queue<string>stringLog;
        mutex mMutexLog;//写log加锁
        int logLevel;//写log等级
    };

    通过参数的不同来调用不同的类的构造函数,达到可变参数的目的。

  • 相关阅读:
    第3章 神经网络
    OpenCV基础(一)---图像卷积运算
    OpenCV-自定义harris检测
    C++类型转换
    剑指offer之【二叉搜索树与双向链表】
    剑指offer之【复杂链表的复制】
    剑指offer之【二叉树中和为某一值的路径】
    剑指offer之【二叉搜索树的后序遍历序列】
    剑指offer之【从上往下打印二叉树】
    剑指offer之【栈的压入、弹出序列】
  • 原文地址:https://www.cnblogs.com/linxisuo/p/14872672.html
Copyright © 2020-2023  润新知