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等级
};

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

原文地址:https://www.cnblogs.com/linxisuo/p/14872672.html