How to use class templates?



  • I assume you may have seen many questions of this kind.But i am trying to execute this, i am trying to implement a template class while executing i am getting below errors.

    Header File

    #ifndef LCDTEMPLATE_H
    #define LCDTEMPLATE_H
    
    #include <QDialog>
    #include <QTimer>
    #include <QDebug>
    #include <QList>
    #include <QPixmap>
    #include <QPalette>
    #include <QStringList>
    
    
    class LcdTemp : public QDialog
    {
        Q_OBJECT
    public:
        LcdTemp();
        QStringList nameList;
    signals:
        void timeout();
    private slots:
        virtual void display() = 0;
        virtual void display(QStringList) = 0;
    
    };
    
    template<typename T>
    class LcdTemplate : public LcdTemp
    {
    public:
        LcdTemplate();
        void display();
        void display(T);
        T Getalue();
        int indexVal;
        T m_Obj;
    };
    
    #endif // CSLCDTEMPLATE_H
    

    CPP File

    #include "LcdTemplate.h"
    
    extern QStringList display_list;
    
    template <typename T>
    LcdTemplate<T>::LcdTemplate()
    {
        qDebug()<<"Inside the Constructor of LCD Template";
    
        setWindowFlags(Qt::FramelessWindowHint);
    #ifdef GL11_QT
        setGeometry(0,0,320,240);
    #endif
    #ifdef GL11_GNOME
        setGeometry(2,20,316,200);
    #endif
        setStyleSheet("background-color:yellow");
    
        indexVal = 0;
    
        QTimer *timer = new QTimer(this); 
        connect(timer, SIGNAL(timeout()), this, SLOT(display()));
        timer->start(500);
    
        QTimer::singleShot(4000, this, SLOT(close()));
    }
    
    template <typename T>
    void LcdTemplate<T>::display()
    {
    
        nameList = display_list;
        qDebug()<<"Data in"<<nameList;
        display(nameList);
    
    }
    template <typename T>
    void LcdTemplate<T>::display(T list)
    {
        switch(indexVal)
        {
        case 0:
            this->setStyleSheet(nameList.at(indexVal));
            indexVal = 1;
            break;
        case 1:
            this->setStyleSheet(nameList.at(indexVal));
            indexVal = 2;
            break;
        case 2:
            this->setStyleSheet(nameList.at(indexVal));
            indexVal = 3;
            break;
        case 4:
            this->setStyleSheet(nameList.at(indexVal));
            indexVal = 4;
            break;
        case 5:
            this->setStyleSheet(nameList.at(indexVal));
            indexVal = 0;
            break;
        }
    }
    
    template <typename T>
    T LcdTemplate<T>::Getalue()
    {
       return m_Obj;
    }
    

    Main

    #include <QApplication>
    #include "LcdTemplate.h"
    
    int main(int argc,char *argv[])
    {
            QApplication a(argc,argv);
            LcdTemplate<QStringList> lcd;
            lcd.show();
    
            a.exec();
    }
    

    Error

    /u01/QtPractice/LcdTemplate/main.cpp:7: undefined reference to `LcdTemplate<QStringList>::LcdTemplate()'
    
    main.o:(.rodata._ZTV11LcdTemplateI11QStringListE[_ZTV11LcdTemplateI11QStringListE]+0xec): undefined reference to `LcdTemplate<QStringList>::display()'
    
    main.o:(.rodata._ZTV11LcdTemplateI11QStringListE[_ZTV11LcdTemplateI11QStringListE]+0xf0): undefined reference to `LcdTemplate<QStringList>::display(QStringList)'
    
    collect2: error: ld returned 1 exit status
    Makefile:100: recipe for target 'LcdTemplate' failed
    make: [LcdTemplate] Error 1
    

    I know i have done some thing wrong with the main

    Guide me to resolve.



  • Templates can't be split in .h/.cpp files, the body must be all in one place

    I don't see the point to your template-ing btw as any template parameter that is not QStringList would make LcdTemplate pure virtual (because virtual void LcdTemp::display(QStringList) = 0;) so you are basically forcing T to be QStringList in any case



  • @VRonin

    Thanks for replying Ronin

    Sorry Ronin i didn't understand your point.

    actually i have split in to .h and .cpp files after reading this article
    https://www.codeproject.com/Articles/48575/How-to-define-a-template-class-in-a-h-file-and-imp



  • Looking at that page, you are currently running into the problem described in the "Linking Issue" section.

    The "solutions" suggested are

    1. Requires you to know in the template cpp file all the template parameters that you will use across the program so, in my opinion, it negates all the benefit of template-ing, with the additional drawback of creating code for every specialised template even if you don't use it somewhere else (there is even more clutter if you forget to include the extern keyword)

    2. Requires you to #include the template cpp every time you #include the header so I see no advantage in splitting the h and cpp file, you end up with 1 more line of code in every case you use the template and no other advantage

    3. it's practically the same as not splitting the .h and .cpp file

    So once again:

    @VRonin said in How to use class templates?:

    Templates can't be split in .h/.cpp files, the body must be all in one place


    This is actually quite a discussed topic nowadays under the broader banner of "modules". There are proposals to include this mechanism in C++.
    The committee for C++17 voted against including them in the standard but it's not excluded they will become part of the language in C++20 iteration



  • @VRonin

    Thanks for you elicit explanation Ronin and your explanation given me a better understandability on templates and their usages.one last question this may look stupid for you, can we use templates in Qt is it recommended or not . .?


  • Moderators

    @Rohith Sure you can use templates and Qt, why not? Qt is just a C++ framework. You can use what ever C++ provides.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.