Search code examples
c++qtqt6

If statement in a template only run the first if-statement - QT


template <class T> void IOcalibrationWindow::setChildIntoIOcalibrationObject(int i, QString firstChildName, QString lastChildName, QString firstIocalibrationMethodName, QString lastIOcalibrationMethodName){
    /* Get the index as string */
    QString index = QString::number(i);

    /* Create the UI field name */
    QString childName = firstChildName + index + lastChildName;

    /* Create the object name */
    const char *IOcalibrationMethodName = (firstIocalibrationMethodName + index + lastIOcalibrationMethodName).toLatin1().data();

    /* Get UI child */
    T *uIchild = findChild<T*>(childName);

    /* Get calibration object */
    const QMetaObject *IOcalibrationMetaObject = iOcalibration.metaObject();

    /* Insert into object */
    if(std::strcmp(T::staticMetaObject.className(), "QDoubleSpinBox") != 0)
        IOcalibrationMetaObject->invokeMethod(&iOcalibration, IOcalibrationMethodName, Qt::DirectConnection, Q_ARG(double, uIchild->value()));
    else if(std::strcmp(T::staticMetaObject.className(), "QLineEdit") != 0)
        IOcalibrationMetaObject->invokeMethod(&iOcalibration, IOcalibrationMethodName, Qt::DirectConnection, Q_ARG(QString, uIchild->text()));

}

This is an if-statement in QT where I'm accessing the specific method inside object iOcalibration. The method name is called IOcalibrationMethodName.

Sometimes the method IOcalibrationMethodName has an argument of double or QString. It all depends on the template T, which can be QDoubleSpinBox or QLineEdit.

When I call the function, you can see that I'm using different templates.

setChildIntoIOcalibrationObject<QDoubleSpinBox>(i, "analogSingleInput", "MaxDoubleSpinBox", "setAnalogSingleInput", "Max");
setChildIntoIOcalibrationObject<QDoubleSpinBox>(i, "analogSingleInput", "MinDoubleSpinBox", "setAnalogSingleInput", "Min");
setChildIntoIOcalibrationObject<QLineEdit>(i, "analogSingleInput", "UnitLineEdit", "setAnalogSingleInput", "Unit");

Problem:

My problem with the code is that when I using the template class QLineEdit, I get an error at this code line.

IOcalibrationMetaObject->invokeMethod(&iOcalibration, IOcalibrationMethodName, Qt::DirectConnection, Q_ARG(double, uIchild->value()));

This should not be possible due to the if-statement. The error is:

iocalibrationwindow.cpp:102:133: error: no member named 'value' in 'QLineEdit'
qobjectdefs.h:95:51: note: expanded from macro 'Q_ARG'
iocalibrationwindow.cpp:80:9: note: in instantiation of function template  
specialization 'IOcalibrationWindow::setChildIntoIOcalibrationObject<QLineEdit>' 
requested here

That means, that the first if-statement runs when I'm using template QLineEdit. But the if-statement checks if the template is QDoubleSpinBox

if(std::strcmp(T::staticMetaObject.className(), "QDoubleSpinBox") != 0)

Question:

How can this be possible that QLineEdit till be equal as QDoubleSpinBox?


Solution

  • I'm not entirely sure what you're trying to do but, from the code that's given, why can't you simply split out the uIchild->* calls into a couple of functions overloads? That would result in something like (untested)...

    QGenericArgument fetch_data (QDoubleSpinBox *p)
    {
      return Q_ARG(double, p->value());
    }
    
    QGenericArgument fetch_data (QLineEdit *p)
    {
      return Q_ARG(QString, p->text());
    }
    
    template <class T> void IOcalibrationWindow::setChildIntoIOcalibrationObject(int i, QString firstChildName, QString lastChildName, QString firstIocalibrationMethodName, QString lastIOcalibrationMethodName){
        /* Get the index as string */
        QString index = QString::number(i);
    
        /* Create the UI field name */
        QString childName = firstChildName + index + lastChildName;
    
        /* Create the object name */
        const char *IOcalibrationMethodName = (firstIocalibrationMethodName + index + lastIOcalibrationMethodName).toLatin1().data();
    
        /* Get UI child */
        T *uIchild = findChild<T*>(childName);
    
        /* Get calibration object */
        const QMetaObject *IOcalibrationMetaObject = iOcalibration.metaObject();
    
        /* Insert into object */
        if(std::strcmp(T::staticMetaObject.className(), "QDoubleSpinBox") == 0)
            IOcalibrationMetaObject->invokeMethod(&iOcalibration, IOcalibrationMethodName, Qt::DirectConnection, fetch_data(uIchild));
        else if(std::strcmp(T::staticMetaObject.className(), "QLineEdit") == 0)
            IOcalibrationMetaObject->invokeMethod(&iOcalibration, IOcalibrationMethodName, Qt::DirectConnection, fetch_data(uIchild));
    
    }
    

    [Note that I've changed the sense of the if (strcmp(... comparisons: strcmp returns zero if the strings are equal.]